diff --git a/src/kubernetes-api/internal/controller/l2network_controller.go b/src/kubernetes-api/internal/controller/l2network_controller.go
index db14b777c2e6f98b9a4d456da0db372e7efc5099..5915f860dc28019e5502e14ca86ba371eec2b8bb 100644
--- a/src/kubernetes-api/internal/controller/l2network_controller.go
+++ b/src/kubernetes-api/internal/controller/l2network_controller.go
@@ -72,17 +72,19 @@ func (r *L2NetworkReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
 
 	// Check if the object is being deleted
 	if network.GetDeletionTimestamp() != nil {
-		if utils.ContainsString(network.GetFinalizers(), "l2network.finalizers.l2sm.k8s.local") {
+		if utils.ContainsString(network.GetFinalizers(), l2smFinalizer) {
 			// The object is being deleted
 			if err := r.InternalClient.DeleteNetwork(network.Spec.Type, network.Name); err != nil {
 				// If fail to delete the external dependency here, return with error
 				// so that it can be retried
+				log.Error(err, "couldn't delete network in sdn controller")
 				return ctrl.Result{}, err
 			}
 
 			// Remove our finalizer from the list and update it.
-			network.SetFinalizers(utils.RemoveString(network.GetFinalizers(), "l2network.finalizers.l2sm.k8s.local"))
+			network.SetFinalizers(utils.RemoveString(network.GetFinalizers(), l2smFinalizer))
 			if err := r.Update(ctx, network); err != nil {
+				log.Error(err, "couldn't remove finalizer to l2network")
 				return ctrl.Result{}, err
 			}
 		}
@@ -92,7 +94,7 @@ func (r *L2NetworkReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
 	}
 
 	// Add finalizer for this CR
-	if !utils.ContainsString(network.GetFinalizers(), "l2network.finalizers.l2sm.k8s.local") {
+	if !utils.ContainsString(network.GetFinalizers(), l2smFinalizer) {
 		err := r.InternalClient.CreateNetwork(network.Spec.Type, sdnclient.VnetPayload{NetworkId: network.Name})
 		if err != nil {
 			log.Error(err, "failed to create network")
@@ -102,13 +104,14 @@ func (r *L2NetworkReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
 		}
 		log.Info("Network created in SDN controller", "NetworkID", network.Name)
 		r.updateControllerStatus(ctx, network, l2smv1.OnlineStatus)
-		network.SetFinalizers(append(network.GetFinalizers(), "l2network.finalizers.l2sm.k8s.local"))
+		network.SetFinalizers(append(network.GetFinalizers(), l2smFinalizer))
 		if err := r.Update(ctx, network); err != nil {
 			return ctrl.Result{}, err
 		}
 	}
 
-	if network.Spec.Type == l2smv1.NetworkTypeExtVnet {
+	// If network is inter domain
+	if network.Spec.Provider != nil {
 		provStatus, err := interDomainReconcile(network, log)
 		if err != nil {
 			log.Error(err, "failed to connect to provider")
@@ -149,6 +152,7 @@ func (r *L2NetworkReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
 	// 	return ctrl.Result{}, statusUpdateErr
 	// }
 
+	log.Info("something in the rain")
 	return ctrl.Result{}, nil
 }
 
diff --git a/src/kubernetes-api/internal/controller/networkedgedevice_controller.go b/src/kubernetes-api/internal/controller/networkedgedevice_controller.go
index a04cc6d4c5e0f5951e0a5ba91ffa15feab229887..ad1a673001e8f82eed9818aa785d7a97dd64e86b 100644
--- a/src/kubernetes-api/internal/controller/networkedgedevice_controller.go
+++ b/src/kubernetes-api/internal/controller/networkedgedevice_controller.go
@@ -41,6 +41,8 @@ type NetworkEdgeDeviceReconciler struct {
 }
 
 var (
+	// name of our custom finalizer
+	l2smFinalizer      = "l2sm.operator.io/finalizer"
 	replicaSetOwnerKey = ".metadata.controller"
 	apiGVStr           = l2smv1.GroupVersion.String()
 )
@@ -73,9 +75,6 @@ func (r *NetworkEdgeDeviceReconciler) Reconcile(ctx context.Context, req ctrl.Re
 		return ctrl.Result{}, client.IgnoreNotFound(err)
 	}
 
-	// name of our custom finalizer
-	l2smFinalizer := "l2sm.operator.io/finalizer"
-
 	// examine DeletionTimestamp to determine if object is under deletion
 	if netEdgeDevice.ObjectMeta.DeletionTimestamp.IsZero() {
 		// The object is not being deleted, so if it does not have our finalizer,
diff --git a/src/kubernetes-api/internal/controller/overlay_controller.go b/src/kubernetes-api/internal/controller/overlay_controller.go
index da2ac7c405439f5d2e8aa6e64e5269a8f224847c..824ab627cf3d751c4db57971ed58323881245c91 100644
--- a/src/kubernetes-api/internal/controller/overlay_controller.go
+++ b/src/kubernetes-api/internal/controller/overlay_controller.go
@@ -71,7 +71,6 @@ func (r *OverlayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
 	}
 
 	// name of our custom finalizer
-	l2smFinalizer := "l2sm.operator.io/finalizer"
 
 	// examine DeletionTimestamp to determine if object is under deletion
 	if overlay.ObjectMeta.DeletionTimestamp.IsZero() {
diff --git a/src/kubernetes-api/internal/controller/pod_controller.go b/src/kubernetes-api/internal/controller/pod_controller.go
index d7f6f2248b0f181e7a439b40ce7146c871c50f91..18897347f9f70e1611527a9b399add7bfd0506f5 100644
--- a/src/kubernetes-api/internal/controller/pod_controller.go
+++ b/src/kubernetes-api/internal/controller/pod_controller.go
@@ -18,17 +18,20 @@ package controller
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"os"
 
 	"github.com/go-logr/logr"
-	nettypes "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	l2smv1 "l2sm.k8s.local/controllermanager/api/v1"
+	"l2sm.k8s.local/controllermanager/internal/nedinterface"
 	"l2sm.k8s.local/controllermanager/internal/sdnclient"
+	"l2sm.k8s.local/controllermanager/internal/utils"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/log"
 )
 
 // PodReconciler reconciles a Pod object
@@ -55,7 +58,7 @@ type PodReconciler struct {
 // For more details, check Reconcile and its Result here:
 // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.17.0/pkg/reconcile
 func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
-	// logger := log.FromContext(ctx)
+	logger := log.FromContext(ctx)
 
 	pod := &corev1.Pod{}
 	err := r.Get(ctx, req.NamespacedName, pod)
@@ -73,100 +76,117 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
 	// Ensure the Multus annotation is correctly formatted and present
 
 	// Check if the object is being deleted
-	// if pod.GetDeletionTimestamp() != nil {
-	// 	if utils.ContainsString(pod.GetFinalizers(), "pod.finalizers.l2sm.k8s.local") {
-	// 		// If the pod is being deleted, we should free the interface, both the net-attach-def crd and the openflow port.
-	// 		// This is done for each interface in the pod.
-	// 		multusAnnotations, ok := pod.Annotations[MULTUS_ANNOTATION_KEY]
-
-	// 		if !ok {
-	// 			logger.Error(nil, "Error detaching the pod from the network attachment definitions")
-	// 			return ctrl.Result{}, nil
-	// 		}
-
-	// 		multusNetAttachDefinitions, err := extractNetworks(pod.Annotations[multusAnnotations], r.SwitchesNamespace)
-
-	// 		if err != nil {
-	// 			logger.Error(nil, "Error detaching the pod from the network attachment definitions")
-	// 			return ctrl.Result{}, nil
-	// 		}
-
-	// 		for _, multusNetAttachDef := range multusNetAttachDefinitions {
-
-	// 			// We liberate the specific attachment from the node, so it can be used again
-	// 			r.DetachNetAttachDef(ctx, multusNetAttachDef, r.SwitchesNamespace)
-
-	// 			// We liberate the port in the onos app
-	// 			// r.InternalClient.DetachPodFromNetwork("vnet",multusNetAttachDef)
-	// 		}
-
-	// 		// Remove our finalizer from the list and update it.
-	// 		pod.SetFinalizers(utils.RemoveString(pod.GetFinalizers(), "pod.finalizers.l2sm.k8s.local"))
-	// 		if err := r.Update(ctx, pod); err != nil {
-	// 			return ctrl.Result{}, err
-	// 		}
-	// 		// Stop reconciliation as the item is being deleted
-	// 		return ctrl.Result{}, nil
-	// 	}
-
-	// 	// If it's not getting deleted, then let's check if it's been created or not
-	// 	// Add finalizer for this CR
-	// 	if !utils.ContainsString(pod.GetFinalizers(), "pod.finalizers.l2sm.k8s.local") {
-
-	// 		networks, err := extractNetworks(pod.Annotations[L2SM_NETWORK_ANNOTATION], r.SwitchesNamespace)
+	if pod.GetDeletionTimestamp() != nil {
+		if utils.ContainsString(pod.GetFinalizers(), l2smFinalizer) {
+			logger.Info("L2S-M Pod deleted: detaching l2network")
+
+			// If the pod is being deleted, we should free the interface, both the net-attach-def crd and the openflow port.
+			// This is done for each interface in the pod.
+			multusAnnotations, ok := pod.Annotations[MULTUS_ANNOTATION_KEY]
+
+			if !ok {
+				logger.Error(nil, "Error detaching the pod from the network attachment definitions")
+				return ctrl.Result{}, nil
+			}
+
+			multusNetAttachDefinitions, err := extractNetworks(pod.Annotations[multusAnnotations], r.SwitchesNamespace)
+
+			if err != nil {
+				logger.Error(nil, "Error detaching the pod from the network attachment definitions")
+				return ctrl.Result{}, nil
+			}
+
+			for _, multusNetAttachDef := range multusNetAttachDefinitions {
+
+				fmt.Println(multusNetAttachDef)
+				// We liberate the specific attachment from the node, so it can be used again
+				//r.DetachNetAttachDef(ctx, multusNetAttachDef, r.SwitchesNamespace)
+
+				// We liberate the port in the onos app
+				//r.InternalClient.DetachPodFromNetwork("vnet",multusNetAttachDef)
+			}
+
+			// Remove our finalizer from the list and update it.
+			pod.SetFinalizers(utils.RemoveString(pod.GetFinalizers(), l2smFinalizer))
+			if err := r.Update(ctx, pod); err != nil {
+				return ctrl.Result{}, err
+			}
+			// Stop reconciliation as the item is being deleted
+			return ctrl.Result{}, nil
+		}
+		// Stop reconciliation as the item is being deleted
+		return ctrl.Result{}, nil
+	}
 
-	// 		if created, _ := r.verifyNetworksAreCreated(ctx, networks); !created {
+	// If it's not getting deleted, then let's check if it's been created or not
+	// Add finalizer for this CR
+	if !utils.ContainsString(pod.GetFinalizers(), l2smFinalizer) {
+		// We add the finalizers now that the pod has been added to the network and we want to keep track of it
+		pod.SetFinalizers(append(pod.GetFinalizers(), l2smFinalizer))
+		if err := r.Update(ctx, pod); err != nil {
+			return ctrl.Result{}, err
+		}
+		logger.Info("L2S-M Pod created: attaching to l2network")
 
-	// 			logger.Error(nil, "Pod's network annotation incorrect. L2Network not attached.")
-	// 			// return admission.Allowed("Pod's network annotation incorrect. L2Network not attached.")
-	// 			return ctrl.Result{}, err
+		networkAnnotations, err := extractNetworks(pod.Annotations[L2SM_NETWORK_ANNOTATION], r.SwitchesNamespace)
 
-	// 		}
-	// 		// Add the pod interfaces to the sdn controller
-	// 		multusAnnotations, ok := pod.Annotations[MULTUS_ANNOTATION_KEY]
+		if err != nil {
+			logger.Error(err, "l2 networks could not be extracted from the pods annotations")
+		}
+		networks, err := GetL2Networks(ctx, r.Client, networkAnnotations)
+		if err != nil {
 
-	// 		if !ok {
-	// 			logger.Error(nil, "Error detaching the pod from the network attachment definitions")
-	// 			return ctrl.Result{}, nil
-	// 		}
+			logger.Error(nil, "Pod's network annotation incorrect. L2Network not attached.")
+			// return admission.Allowed("Pod's network annotation incorrect. L2Network not attached.")
+			return ctrl.Result{}, err
 
-	// 		multusNetAttachDefinitions, err := extractNetworks(pod.Annotations[multusAnnotations], r.SwitchesNamespace)
+		}
+		// Add the pod interfaces to the sdn controller
+		multusAnnotations, ok := pod.Annotations[MULTUS_ANNOTATION_KEY]
 
-	// 		if err != nil {
-	// 			logger.Error(nil, "Error detaching the pod from the network attachment definitions")
-	// 			return ctrl.Result{}, nil
-	// 		}
+		if !ok {
+			logger.Error(nil, "Error detaching the pod from the network attachment definitions")
+			return ctrl.Result{}, nil
+		}
 
-	// 		fmt.Println(multusNetAttachDefinitions)
+		multusNetAttachDefinitions, err := extractNetworks(multusAnnotations, r.SwitchesNamespace)
 
-	// 		// ofID := r.GetOpenflowId(ctx, pod.Spec.NodeName)
+		if err != nil || len(multusNetAttachDefinitions) != len(networkAnnotations) {
+			logger.Error(nil, "Error detaching the pod from the network attachment definitions")
+			return ctrl.Result{}, nil
+		}
 
-	// 		// for index, network := range networks {
+		ofID := fmt.Sprintf("of:%s", utils.GenerateDatapathID(pod.Spec.NodeName))
 
-	// 		// 	portNumber, _ := utils.GetPortNumberFromNetAttachDef(multusNetAttachDefinitions[index].Name)
-	// 		// 	ofPort := fmt.Sprintf("%s/%s", ofID, portNumber)
+		for index, network := range networks {
+			portNumber, _ := utils.GetPortNumberFromNetAttachDef(multusNetAttachDefinitions[index].Name)
+			ofPort := fmt.Sprintf("%s/%s", ofID, portNumber)
 
-	// 		// 	r.InternalClient.AttachPodToNetwork("vnets", sdnclient.VnetPortPayload{NetworkId: network.Name, Port: []string{ofPort}})
-	// 		// }
+			err = r.InternalClient.AttachPodToNetwork("vnets", sdnclient.VnetPortPayload{NetworkId: network.Name, Port: []string{ofPort}})
+			if err != nil {
+				logger.Error(err, "Error attaching pod to the l2network")
+				return ctrl.Result{}, nil
+			}
 
-	// 		// We add the finalizers now that the pod has been added to the network and we want to keep track of it
-	// 		pod.SetFinalizers(append(pod.GetFinalizers(), "pod.finalizers.l2sm.k8s.local"))
-	// 		if err := r.Update(ctx, pod); err != nil {
-	// 			return ctrl.Result{}, err
-	// 		}
-	// 	}
+			// If the L2Network is of type inter-domain (has a provider), attach the associated NED
+			// and communicate with it
+			if network.Spec.Provider != nil {
 
-	// }
+				gatewayNodeName, err := r.CreateNewNEDConnection(network)
+				if err != nil {
+					return ctrl.Result{}, nil
+				}
 
-	// r.GetOpenflowId(ctx,pod.Spec.NodeName)
+				err = r.ConnectGatewaySwitchToNED(ctx, network.Name, gatewayNodeName)
+				if err != nil {
+					return ctrl.Result{}, nil
+				}
 
-	// for _, network := range networks {
+			}
+		}
 
-	// 	ofPort := fmt.Sprintf("%s/%s",ofID,portNumber)
-	// 	sdnclient.VnetPortPayload{NetworkId: network.Name, Port: ofPort}
+	}
 
-	// 	r.InternalClient.AttachPodToNetwork()
-	// }
 	return ctrl.Result{}, nil
 
 }
@@ -191,92 +211,63 @@ func (r *PodReconciler) SetupWithManager(mgr ctrl.Manager) error {
 		Complete(r)
 }
 
-func (r *PodReconciler) verifyNetworksAreCreated(ctx context.Context, networks []NetworkAnnotation) (bool, error) {
-	// List all L2Networks
-	l2Networks := &l2smv1.L2NetworkList{}
-	if err := r.List(ctx, l2Networks); err != nil {
-		return false, err
+func (r *PodReconciler) CreateNewNEDConnection(network l2smv1.L2Network) (string, error) {
+
+	clientConfig := sdnclient.ClientConfig{BaseURL: fmt.Sprintf("http://%s/onos/v1", network.Spec.Provider.Domain), Username: "karaf", Password: "karaf"}
+
+	externalClient, err := sdnclient.NewClient(sdnclient.InternalType, clientConfig)
+
+	if err != nil {
+		return "", err
+		// logger.Error(err, "no connection could be made with external sdn controller")
 	}
+	gatewayNodeName, nedPortNumber := nedinterface.GetConnectionInfo()
+
+	nedOFID := fmt.Sprintf("of:%s", utils.GenerateDatapathID(fmt.Sprintf("%s%s", gatewayNodeName, network.Spec.Provider.Name)))
+	nedOFPort := fmt.Sprintf("%s/%s", nedOFID, nedPortNumber)
+
+	err = externalClient.AttachPodToNetwork("vnets", sdnclient.VnetPortPayload{NetworkId: network.Name, Port: []string{nedOFPort}})
+	if err != nil {
+		return "", errors.Join(err, errors.New("could not update network attachment definition"))
 
-	// Create a map of existing L2Network names for quick lookup
-	existingNetworks := make(map[string]struct{})
-	for _, network := range l2Networks.Items {
-		existingNetworks[network.Name] = struct{}{}
 	}
+	return gatewayNodeName, nil
+}
 
-	// Verify if each annotated network exists
-	for _, net := range networks {
-		if _, exists := existingNetworks[net.Name]; !exists {
-			return false, nil
-		}
+func (r *PodReconciler) ConnectGatewaySwitchToNED(ctx context.Context, networkName, gatewayNodeName string) error {
+
+	var err error
+	netAttachDefLabel := NET_ATTACH_LABEL_PREFIX + gatewayNodeName
+	netAttachDefs := GetFreeNetAttachDefs(ctx, r.Client, r.SwitchesNamespace, netAttachDefLabel)
 
+	if len(netAttachDefs.Items) == 0 {
+		err = errors.New("no interfaces available in control plane node")
+		//logger.Error(err, fmt.Sprintf("No interfaces available for node %s", gatewayNodeName))
+		return err
 	}
 
-	return true, nil
-}
+	netAttachDef := &netAttachDefs.Items[0]
+
+	portNumber, _ := utils.GetPortNumberFromNetAttachDef(netAttachDef.Name)
+
+	gatewayOFID := fmt.Sprintf("of:%s", utils.GenerateDatapathID(gatewayNodeName))
+
+	gatewayOFPort := fmt.Sprintf("%s/%s", gatewayOFID, portNumber)
 
-func (r *PodReconciler) DetachNetAttachDef(ctx context.Context, multusNetAttachDef NetworkAnnotation, namespace string) error {
+	err = r.InternalClient.AttachPodToNetwork("vnets", sdnclient.VnetPortPayload{NetworkId: networkName, Port: []string{gatewayOFPort}})
 
-	netAttachDef := &nettypes.NetworkAttachmentDefinition{}
-	err := r.Get(ctx, client.ObjectKey{
-		Name:      multusNetAttachDef.Name,
-		Namespace: namespace,
-	}, netAttachDef)
 	if err != nil {
 		return err
+		//logger.Error(err, "could not make a connection between the gateway switch and the NED. Internal SDN controller error.")
 	}
-	err = r.Delete(ctx, netAttachDef)
-	return err
 
-}
+	netAttachDef.Labels[netAttachDefLabel] = "true"
+	err = r.Client.Update(ctx, netAttachDef)
+	if err != nil {
+		return err
+		//.Error(err, "Could not update network attachment definition")
+
+	}
 
-func (r *PodReconciler) GetOpenflowId(ctx context.Context, nodename string) (string, error) {
-	return "", nil
-	// // Define the list options with the namespace
-	// listOptions := &client.ListOptions{
-	//     Namespace: r.SwitchesNamespace,
-	// }
-
-	// // List all pods in the namespace
-	// podList := &corev1.PodList{}
-	// if err := r.List(ctx, podList, listOptions); err != nil {
-	//     return "", fmt.Errorf("failed to list pods: %w", err)
-	// }
-
-	// // Iterate through the pods to find the one on the specified node
-	// var switchPod *corev1.Pod
-	// for _, pod := range podList.Items {
-	//     if pod.Spec.NodeName == nodename {
-	//         switchPod = &pod
-	//         break
-	//     }
-	// }
-
-	// if switchPod == nil {
-	//     return "", fmt.Errorf("pod not found on node: %s", nodename)
-	// }
-
-	// // Check if the OpenFlow ID is already annotated
-	// if openflowID, exists := switchPod.Annotations["openflow-id"]; exists && openflowID != "" {
-	//     return openflowID, nil
-	// }
-
-	// // Retrieve the OpenFlow ID (replace this with your actual logic)
-	// openflowID, err := r.InternalClient.RetrieveOpenflowID(switchPod.)
-	// if err != nil {
-	//     return "", fmt.Errorf("failed to retrieve openflow id: %w", err)
-	// }
-
-	// // Annotate the pod with the OpenFlow ID
-	// if switchPod.Annotations == nil {
-	//     switchPod.Annotations = make(map[string]string)
-	// }
-	// switchPod.Annotations["openflow-id"] = openflowID
-
-	// // Update the pod with the new annotation
-	// if err := r.Update(ctx, switchPod); err != nil {
-	//     return "", fmt.Errorf("failed to update pod with openflow id: %w", err)
-	// }
-
-	// return openflowID, nil
+	return nil
 }
diff --git a/src/kubernetes-api/internal/controller/pod_utils.go b/src/kubernetes-api/internal/controller/pod_utils.go
new file mode 100644
index 0000000000000000000000000000000000000000..50796fb2d068667edf0820b58da4f39ee05d747f
--- /dev/null
+++ b/src/kubernetes-api/internal/controller/pod_utils.go
@@ -0,0 +1,142 @@
+package controller
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"math/rand"
+	"strings"
+	"time"
+
+	nettypes "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
+	"k8s.io/apimachinery/pkg/labels"
+	"k8s.io/apimachinery/pkg/selection"
+	l2smv1 "l2sm.k8s.local/controllermanager/api/v1"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+const (
+	NET_ATTACH_LABEL_PREFIX = "used-"
+	L2SM_NETWORK_ANNOTATION = "l2sm/networks"
+	MULTUS_ANNOTATION_KEY   = "k8s.v1.cni.cncf.io/networks"
+)
+
+type NetworkAnnotation struct {
+	Name       string   `json:"name"`
+	Namespace  string   `json:"namespace,omitempty"`
+	IPAdresses []string `json:"ips,omitempty"`
+}
+
+func extractNetworks(annotations, namespace string) ([]NetworkAnnotation, error) {
+
+	var networks []NetworkAnnotation
+	err := json.Unmarshal([]byte(annotations), &networks)
+	if err != nil {
+		// If unmarshalling fails, treat as comma-separated list
+		names := strings.Split(annotations, ",")
+
+		for _, name := range names {
+			name = strings.TrimSpace(name)
+			if name != "" {
+				networks = append(networks, NetworkAnnotation{Name: name})
+			}
+		}
+	}
+
+	// Iterate over the networks to check if any IPAddresses are missing
+	for i := range networks {
+		if len(networks[i].IPAdresses) == 0 {
+			// Call GenerateIPv6Address if IPAddresses are missing
+			networks[i].GenerateIPv6Address()
+		}
+		networks[i].Namespace = namespace
+	}
+	return networks, nil
+}
+
+func GetL2Networks(ctx context.Context, c client.Client, networks []NetworkAnnotation) ([]l2smv1.L2Network, error) {
+	// List all L2Networks
+	l2Networks := &l2smv1.L2NetworkList{}
+	if err := c.List(ctx, l2Networks); err != nil {
+		return []l2smv1.L2Network{}, err
+	}
+
+	// Create a map of existing L2Network names to L2Network objects for quick lookup
+	existingNetworks := make(map[string]l2smv1.L2Network)
+	for _, network := range l2Networks.Items {
+		existingNetworks[network.Name] = network
+	}
+
+	// Collect the L2Networks that match the requested networks
+	var result l2smv1.L2NetworkList
+	for _, net := range networks {
+		if l2net, exists := existingNetworks[net.Name]; exists {
+			result.Items = append(result.Items, l2net)
+		} else {
+			return result.Items, fmt.Errorf("network %s doesn't exist", net.Name)
+		}
+	}
+
+	return result.Items, nil
+}
+
+func GetFreeNetAttachDefs(ctx context.Context, c client.Client, switchesNamespace, label string) nettypes.NetworkAttachmentDefinitionList {
+
+	// We define the network attachment definition list that will be later filled.
+	freeNetAttachDef := &nettypes.NetworkAttachmentDefinitionList{}
+
+	// We specify which net-attach-def we want. We want the ones that are specific to l2sm, in the overlay namespace and available in the desired node.
+	nodeSelector := labels.NewSelector()
+
+	nodeRequirement, _ := labels.NewRequirement(label, selection.NotIn, []string{"true"})
+	l2smRequirement, _ := labels.NewRequirement("app", selection.Equals, []string{"l2sm"})
+
+	nodeSelector.Add(*nodeRequirement)
+	nodeSelector.Add(*l2smRequirement)
+
+	listOptions := client.ListOptions{LabelSelector: nodeSelector, Namespace: switchesNamespace}
+
+	// We get the net-attach-def with the corresponding list options
+	c.List(ctx, freeNetAttachDef, &listOptions)
+	return *freeNetAttachDef
+
+}
+
+func (network *NetworkAnnotation) GenerateIPv6Address() {
+	rand.Seed(time.Now().UnixNano())
+
+	// Generating the interface ID (64 bits)
+	interfaceID := rand.Uint64()
+
+	// Formatting to a 16 character hexadecimal string
+	interfaceIDHex := fmt.Sprintf("%016x", interfaceID)
+
+	// Constructing the full IPv6 address in the fe80::/64 range
+	ipv6Address := fmt.Sprintf("fe80::%s:%s:%s:%s/64",
+		interfaceIDHex[:4], interfaceIDHex[4:8], interfaceIDHex[8:12], interfaceIDHex[12:])
+
+	network.IPAdresses = append(network.IPAdresses, ipv6Address)
+
+}
+func multusAnnotationToString(multusAnnotations []NetworkAnnotation) string {
+	jsonData, err := json.Marshal(multusAnnotations)
+	if err != nil {
+		return ""
+	}
+	return string(jsonData)
+}
+
+func (r *PodReconciler) DetachNetAttachDef(ctx context.Context, multusNetAttachDef NetworkAnnotation, namespace string) error {
+
+	netAttachDef := &nettypes.NetworkAttachmentDefinition{}
+	err := r.Get(ctx, client.ObjectKey{
+		Name:      multusNetAttachDef.Name,
+		Namespace: namespace,
+	}, netAttachDef)
+	if err != nil {
+		return err
+	}
+	err = r.Delete(ctx, netAttachDef)
+	return err
+
+}
diff --git a/src/kubernetes-api/internal/controller/pod_webhook.go b/src/kubernetes-api/internal/controller/pod_webhook.go
index 0a7f3fca15d49baf2ef62ebcc0e876d0c20eaf2d..40261118faa40d72fa77d06cbfc1dbc147ab1566 100644
--- a/src/kubernetes-api/internal/controller/pod_webhook.go
+++ b/src/kubernetes-api/internal/controller/pod_webhook.go
@@ -4,28 +4,15 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"math/rand"
 	"net/http"
-	"strings"
-	"time"
 
-	nettypes "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
 	"sigs.k8s.io/controller-runtime/pkg/log"
 
 	corev1 "k8s.io/api/core/v1"
-	"k8s.io/apimachinery/pkg/labels"
-	"k8s.io/apimachinery/pkg/selection"
-	l2smv1 "l2sm.k8s.local/controllermanager/api/v1"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 )
 
-const (
-	NET_ATTACH_LABEL_PREFIX = "used-"
-	L2SM_NETWORK_ANNOTATION = "l2sm/networks"
-	MULTUS_ANNOTATION_KEY   = "k8s.v1.cni.cncf.io/networks"
-)
-
 // +kubebuilder:webhook:path=/mutate-v1-pod,mutating=true,failurePolicy=fail,groups="",resources=pods,verbs=create;update,versions=v1,name=mpod.kb.io
 type PodAnnotator struct {
 	Client            client.Client
@@ -33,12 +20,6 @@ type PodAnnotator struct {
 	SwitchesNamespace string
 }
 
-type NetworkAnnotation struct {
-	Name       string   `json:"name"`
-	Namespace  string   `json:"namespace,omitempty"`
-	IPAdresses []string `json:"ips,omitempty"`
-}
-
 func (a *PodAnnotator) Handle(ctx context.Context, req admission.Request) admission.Response {
 	log := log.FromContext(ctx)
 	log.Info("Registering pod")
@@ -51,7 +32,7 @@ func (a *PodAnnotator) Handle(ctx context.Context, req admission.Request) admiss
 		return admission.Errored(http.StatusBadRequest, err)
 	}
 	if pod.Spec.NodeName == "" {
-		return admission.Errored(http.StatusBadRequest, fmt.Errorf("Pod hasn't got a node assigned to it"))
+		return admission.Errored(http.StatusBadRequest, fmt.Errorf("pod hasn't got a node assigned to it"))
 	}
 
 	// Check if the pod has the annotation l2sm/networks. This webhook operation only will happen if so. Else, it will just
@@ -69,7 +50,7 @@ func (a *PodAnnotator) Handle(ctx context.Context, req admission.Request) admiss
 			return admission.Errored(http.StatusInternalServerError, err)
 		}
 
-		if created, _ := a.verifyNetworksAreCreated(ctx, networks); !created {
+		if _, err := GetL2Networks(ctx, a.Client, networks); err != nil {
 			log.Info("Pod's network annotation incorrect. L2Network not attached.")
 			// return admission.Allowed("Pod's network annotation incorrect. L2Network not attached.")
 
@@ -78,7 +59,7 @@ func (a *PodAnnotator) Handle(ctx context.Context, req admission.Request) admiss
 		// We get the available network attachment definitions. These are interfaces attached to the switches, so
 		// by using labelling, we can know which interfaces the switch has.
 		var multusAnnotations []NetworkAnnotation
-		netAttachDefs := a.getFreeNetAttachDefs(ctx, netAttachDefLabel)
+		netAttachDefs := GetFreeNetAttachDefs(ctx, a.Client, a.SwitchesNamespace, netAttachDefLabel)
 
 		// If there are no available network attachment definitions, we can't attach the pod to the desired networks
 		// So, we launch an error.
@@ -123,100 +104,3 @@ func (a *PodAnnotator) InjectDecoder(d *admission.Decoder) error {
 	a.Decoder = d
 	return nil
 }
-
-func extractNetworks(annotations, namespace string) ([]NetworkAnnotation, error) {
-
-	var networks []NetworkAnnotation
-	err := json.Unmarshal([]byte(annotations), &networks)
-	if err != nil {
-		// If unmarshalling fails, treat as comma-separated list
-		names := strings.Split(annotations, ",")
-		for _, name := range names {
-			name = strings.TrimSpace(name)
-			if name != "" {
-				networks = append(networks, NetworkAnnotation{Name: name})
-			}
-		}
-	}
-
-	// Iterate over the networks to check if any IPAddresses are missing
-	for i := range networks {
-		if len(networks[i].IPAdresses) == 0 {
-			// Call GenerateIPv6Address if IPAddresses are missing
-			networks[i].GenerateIPv6Address()
-		}
-		networks[i].Namespace = namespace
-	}
-
-	return networks, nil
-}
-
-func (a *PodAnnotator) verifyNetworksAreCreated(ctx context.Context, networks []NetworkAnnotation) (bool, error) {
-	// List all L2Networks
-	l2Networks := &l2smv1.L2NetworkList{}
-	if err := a.Client.List(ctx, l2Networks); err != nil {
-		return false, err
-	}
-
-	// Create a map of existing L2Network names for quick lookup
-	existingNetworks := make(map[string]struct{})
-	for _, network := range l2Networks.Items {
-		existingNetworks[network.Name] = struct{}{}
-	}
-
-	// Verify if each annotated network exists
-	for _, net := range networks {
-		if _, exists := existingNetworks[net.Name]; !exists {
-			return false, nil
-		}
-
-	}
-
-	return true, nil
-}
-
-func (a *PodAnnotator) getFreeNetAttachDefs(ctx context.Context, nodeName string) nettypes.NetworkAttachmentDefinitionList {
-
-	// We define the network attachment definition list that will be later filled.
-	freeNetAttachDef := &nettypes.NetworkAttachmentDefinitionList{}
-
-	// We specify which net-attach-def we want. We want the ones that are specific to l2sm, in the overlay namespace and available in the desired node.
-	nodeSelector := labels.NewSelector()
-
-	nodeRequirement, _ := labels.NewRequirement(fmt.Sprintf("%s%s", NET_ATTACH_LABEL_PREFIX, nodeName), selection.NotIn, []string{"true"})
-	l2smRequirement, _ := labels.NewRequirement("app", selection.Equals, []string{"l2sm"})
-
-	nodeSelector.Add(*nodeRequirement)
-	nodeSelector.Add(*l2smRequirement)
-
-	listOptions := client.ListOptions{LabelSelector: nodeSelector, Namespace: a.SwitchesNamespace}
-
-	// We get the net-attach-def with the corresponding list options
-	a.Client.List(ctx, freeNetAttachDef, &listOptions)
-	return *freeNetAttachDef
-
-}
-
-func (network *NetworkAnnotation) GenerateIPv6Address() {
-	rand.Seed(time.Now().UnixNano())
-
-	// Generating the interface ID (64 bits)
-	interfaceID := rand.Uint64()
-
-	// Formatting to a 16 character hexadecimal string
-	interfaceIDHex := fmt.Sprintf("%016x", interfaceID)
-
-	// Constructing the full IPv6 address in the fe80::/64 range
-	ipv6Address := fmt.Sprintf("fe80::%s:%s:%s:%s/64",
-		interfaceIDHex[:4], interfaceIDHex[4:8], interfaceIDHex[8:12], interfaceIDHex[12:])
-
-	network.IPAdresses = append(network.IPAdresses, ipv6Address)
-
-}
-func multusAnnotationToString(multusAnnotations []NetworkAnnotation) string {
-	jsonData, err := json.Marshal(multusAnnotations)
-	if err != nil {
-		return ""
-	}
-	return string(jsonData)
-}