diff --git a/ekms/cmd/start.go b/ekms/cmd/start.go
index 21b6842ec631e8bf8838b929fbad0cc8af7cd97c..3f2ee00d162a9e32263ed351504259fca0d29282 100644
--- a/ekms/cmd/start.go
+++ b/ekms/cmd/start.go
@@ -108,9 +108,9 @@ var startCmd = &cobra.Command{
 		handlers := []handler.PathHandler{
 			system.NewHostnameHandler(),
 			system.NewMemoryHandler(),
-			system.NewMotdHandler(),
 			system.NewStateHandler(),
 			system.NewSystemHandler(),
+			danet.NewCreateRouteHandler(ekmsClient),
 			danet.NewKmsHandler(ekmsClient),
 			danet.NewPeerHandler(ekmsClient),
 			danet.NewKeyRoutingSessionHandler(ekmsClient),
diff --git a/ekms/etsiqkdnclient/etsi-qkdn-client.go b/ekms/etsiqkdnclient/etsi-qkdn-client.go
index 9f4081fa8f157b4a3f249edf8b30ed330d1834c3..9c9e5c191eca9f22ca8b6fc828e6a45fd3553008 100644
--- a/ekms/etsiqkdnclient/etsi-qkdn-client.go
+++ b/ekms/etsiqkdnclient/etsi-qkdn-client.go
@@ -154,13 +154,13 @@ func NewEkmsClient(config *Config) (myInfo *ekmsInfo) {
 	myInfo.KmsPeerUpdateChannel = make(chan string)
 
 	log.Printf("%s in regular operations mode", config.Name)
-	myInfo.kms = emulatedKMS(config, ekmsId, myInfo.KmsPeerUpdateChannel)
+	myInfo.kms = emulatedKMS(config, ekmsId)
 
 	return myInfo
 }
 
 // TODO: return an error.
-func emulatedKMS(config *Config, id uuid.UUID, peerChannel chan string) *kms.EKMS {
+func emulatedKMS(config *Config, id uuid.UUID) *kms.EKMS {
 	// Attach to eKMS
 	emuKMS := kms.NewEKMS(config.Name, id, os.Stdout, log.GetLevel(), false, config.InterComAddr, config.AkmsURL)
 
diff --git a/ekms/handlers/danet/assignForwardingHandler.go b/ekms/handlers/danet/assignForwardingHandler.go
index bc0b188101b4503c578ea8a8676062fbe191a6c8..09d74a5d189b5dc306a2e3663998072d0329eb5c 100644
--- a/ekms/handlers/danet/assignForwardingHandler.go
+++ b/ekms/handlers/danet/assignForwardingHandler.go
@@ -3,6 +3,7 @@ package danet
 import (
 	"fmt"
 
+	"code.fbi.h-da.de/danet/gnmi-target/handler"
 	"code.fbi.h-da.de/danet/quant/ekms/etsiqkdnclient"
 	"code.fbi.h-da.de/danet/quant/ekms/internal/kms"
 	gnmitargetygot "code.fbi.h-da.de/danet/quant/ekms/model"
@@ -13,32 +14,28 @@ import (
 
 // AssignForwardingHandler is the implementation of a gnmitarget.PathHandler.
 type AssignForwardingHandler struct {
-	name       string
-	paths      map[string]struct{}
+	handler.DefaultPathHandler
 	ekmsClient etsiqkdnclient.EkmsClient
 }
 
 func NewAssignForwardingHandler(client etsiqkdnclient.EkmsClient) *AssignForwardingHandler {
 	return &AssignForwardingHandler{
-		name: "assign-forwarding-handler",
-		paths: map[string]struct{}{
-			"/assign-forwarding": {},
+		DefaultPathHandler: handler.DefaultPathHandler{
+			Name: "kms-assign-forwarding-handler",
+			Paths: map[string]struct{}{
+				"/assign-forwarding": {},
+			},
 		},
 		ekmsClient: client,
 	}
 }
 
-func (yh *AssignForwardingHandler) Name() string {
-	return yh.name
-}
-
-func (yh *AssignForwardingHandler) Paths() map[string]struct{} {
-	return yh.paths
-}
-
-func (yh *AssignForwardingHandler) Init(c ygot.ValidatedGoStruct) error {
+func (yh *AssignForwardingHandler) Init(config *handler.Config, publishToSubsFunc func([]*gnmi.Notification) error) error {
 	// A initialization is not needed for this handler. The default startup has
 	// no assign forwarding applied.
+	yh.Config = config
+	yh.PublishToSubs = publishToSubsFunc
+
 	return nil
 }
 
diff --git a/ekms/handlers/danet/createRouteHandler.go b/ekms/handlers/danet/createRouteHandler.go
new file mode 100644
index 0000000000000000000000000000000000000000..2dbf42b7df2cb049d1602b6ee90e87335fac49f3
--- /dev/null
+++ b/ekms/handlers/danet/createRouteHandler.go
@@ -0,0 +1,133 @@
+package danet
+
+import (
+	"fmt"
+
+	"code.fbi.h-da.de/danet/gnmi-target/handler"
+	"code.fbi.h-da.de/danet/quant/ekms/etsiqkdnclient"
+	"code.fbi.h-da.de/danet/quant/ekms/internal/kms/event"
+	gnmitargetygot "code.fbi.h-da.de/danet/quant/ekms/model"
+	"github.com/openconfig/gnmi/proto/gnmi"
+	"github.com/openconfig/ygot/ygot"
+	log "github.com/sirupsen/logrus"
+)
+
+type CreateRouteHandler struct {
+	handler.DefaultPathHandler
+	ekmsClient etsiqkdnclient.EkmsClient
+	events     <-chan event.Event
+}
+
+func NewCreateRouteHandler(client etsiqkdnclient.EkmsClient) *CreateRouteHandler {
+	return &CreateRouteHandler{
+		DefaultPathHandler: handler.DefaultPathHandler{
+			Name: "kms-create-route-handler",
+			Paths: map[string]struct{}{
+				"/create-route-requests": {},
+			},
+		},
+		ekmsClient: client,
+	}
+}
+
+func (yh *CreateRouteHandler) Init(config *handler.Config, publishToSubsFunc func([]*gnmi.Notification) error) error {
+	yh.Config = config
+	yh.PublishToSubs = publishToSubsFunc
+
+	var err error
+	yh.events, err = yh.ekmsClient.Ekms().EventBus().Subscribe(event.CREATE_ROUTE)
+	if err != nil {
+		return err
+	}
+
+	yh.Config.Lock()
+	defer yh.Config.Unlock()
+
+	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
+	if err != nil {
+		return err
+	}
+
+	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
+	if !ok {
+		return fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
+	}
+
+	newConfig.GetOrCreateCreateRouteRequests()
+
+	//validate struct
+	if err := newConfig.Validate(); err != nil {
+		return err
+	}
+
+	yh.Config.Data = newConfig
+
+	// Start the go routine that takes care of any update from the kms
+	go func() {
+		for {
+			select {
+			case e := <-yh.events:
+				log.Println("Update for create route requests.")
+
+				createRouteEvent, ok := e.(*event.CreateRouteEvent)
+				if !ok {
+					log.Errorf("Type assertion failed, expected: %T, got: %T", (*event.CreateRouteEvent)(nil), e)
+					break
+				}
+				diff, err := yh.createRouteRequest(createRouteEvent)
+				if err != nil {
+					log.Errorf("Error within interface subscription goroutine; %v", err)
+					break
+				}
+				if err := yh.PublishToSubs(diff); err != nil {
+					log.Errorf("Error within interface subscription goroutine; %v", err)
+				}
+			}
+		}
+	}()
+
+	return nil
+}
+
+func (yh *CreateRouteHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update) error {
+	return fmt.Errorf("Not implemented")
+}
+
+func (yh *CreateRouteHandler) createRouteRequest(event *event.CreateRouteEvent) ([]*gnmi.Notification, error) {
+	yh.Config.Lock()
+	defer yh.Config.Unlock()
+
+	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
+	if err != nil {
+		return nil, err
+	}
+
+	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
+	if !ok {
+		return nil, fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
+	}
+
+	confCreateRouteRequests := newConfig.GetOrCreateCreateRouteRequests()
+	confCreateRouteRequest, err := confCreateRouteRequests.NewCreateRouteRequest(event.KmsPathId)
+	if err != nil {
+		return nil, err
+	}
+
+	confCreateRouteRequest.KmsPathId = ygot.String(event.KmsPathId)
+	confCreateRouteRequest.RequestStatus = gnmitargetygot.Temp_CreateRouteRequests_CreateRouteRequest_RequestStatus_PENDING
+	confCreateRouteRequest.RemoteUkmsId = ygot.String(event.RemoteUkmsId)
+
+	//validate struct
+	if err := newConfig.Validate(); err != nil {
+		return nil, err
+	}
+
+	notifications, err := ygot.DiffWithAtomic(yh.Config.Data, newConfig)
+	if err != nil {
+		return nil, err
+	}
+
+	yh.Config.Data = newConfig
+
+	return notifications, nil
+}
diff --git a/ekms/handlers/danet/keyRoutingSessionsHandler.go b/ekms/handlers/danet/keyRoutingSessionsHandler.go
index 68073274e2289324894cef705fa8a624ef53a815..bd08a217c0900a4abf5d92fd4e045eba7b2654eb 100644
--- a/ekms/handlers/danet/keyRoutingSessionsHandler.go
+++ b/ekms/handlers/danet/keyRoutingSessionsHandler.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"strings"
 
+	"code.fbi.h-da.de/danet/gnmi-target/handler"
 	"code.fbi.h-da.de/danet/quant/ekms/etsiqkdnclient"
 	"code.fbi.h-da.de/danet/quant/ekms/internal/kms"
 	"code.fbi.h-da.de/danet/quant/ekms/internal/kms/event"
@@ -13,42 +14,27 @@ import (
 	log "github.com/sirupsen/logrus"
 )
 
-type InitiatingKMS struct {
-	Id      string
-	Address string
-}
-
 type KeyRoutingSessionHandler struct {
-	name       string
-	paths      map[string]struct{}
+	handler.DefaultPathHandler
 	ekmsClient etsiqkdnclient.EkmsClient
 	events     <-chan event.Event
 }
 
 func NewKeyRoutingSessionHandler(client etsiqkdnclient.EkmsClient) *KeyRoutingSessionHandler {
 	return &KeyRoutingSessionHandler{
-		name: "kms-handler",
-		paths: map[string]struct{}{
-			// TODO:change to right path
-			"/key-routing-sessions": {},
+		DefaultPathHandler: handler.DefaultPathHandler{
+			Name: "kms-key-routing-session-handler",
+			Paths: map[string]struct{}{
+				"/key-routing-sessions": {},
+			},
 		},
 		ekmsClient: client,
 	}
 }
 
-func (yh *KeyRoutingSessionHandler) Name() string {
-	return yh.name
-}
-
-func (yh *KeyRoutingSessionHandler) Paths() map[string]struct{} {
-	return yh.paths
-}
-
-func (yh *KeyRoutingSessionHandler) Init(c ygot.ValidatedGoStruct) error {
-	config, ok := c.(*gnmitargetygot.Gnmitarget)
-	if !ok {
-		return fmt.Errorf("failed type assertion for newConfig %T", (*gnmitargetygot.Gnmitarget)(nil))
-	}
+func (yh *KeyRoutingSessionHandler) Init(config *handler.Config, publishToSubsFunc func([]*gnmi.Notification) error) error {
+	yh.Config = config
+	yh.PublishToSubs = publishToSubsFunc
 
 	var err error
 	yh.events, err = yh.ekmsClient.Ekms().EventBus().Subscribe(event.ROUTE)
@@ -56,11 +42,8 @@ func (yh *KeyRoutingSessionHandler) Init(c ygot.ValidatedGoStruct) error {
 		return err
 	}
 
-	// Create ygot structs for the kms
-	confKeyRoutingSessions := config.GetOrCreateKeyRoutingSessions()
-
 	// Fill out the known fields in the ygot structs
-	err = updateOrCreateKeyRoutingSessions(confKeyRoutingSessions, yh.ekmsClient)
+	_, err = yh.updateOrCreateKeyRoutingSessions(yh.ekmsClient)
 	if err != nil {
 		return err
 	}
@@ -71,8 +54,14 @@ func (yh *KeyRoutingSessionHandler) Init(c ygot.ValidatedGoStruct) error {
 			select {
 			case <-yh.events:
 				log.Println("Update for Routes.")
-				if err := updateOrCreateKeyRoutingSessions(confKeyRoutingSessions, yh.ekmsClient); err != nil {
-					log.Println("Error within route update goroutine.")
+				diff, err := yh.updateOrCreateKeyRoutingSessions(yh.ekmsClient)
+				if err != nil {
+					log.Errorf("Error within interface subscription goroutine; %v", err)
+					// TODO: check again
+					break
+				}
+				if err := yh.PublishToSubs(diff); err != nil {
+					log.Errorf("Error within interface subscription goroutine; %v", err)
 				}
 			}
 		}
@@ -82,7 +71,7 @@ func (yh *KeyRoutingSessionHandler) Init(c ygot.ValidatedGoStruct) error {
 }
 
 func (yh *KeyRoutingSessionHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update) error {
-	fmt.Println("Update request received for ", yh.name)
+	fmt.Println("Update request received for ", yh.Name)
 	config, ok := c.(*gnmitargetygot.Gnmitarget)
 	if !ok {
 		return fmt.Errorf("failed type assertion for config %T", (*gnmitargetygot.Gnmitarget)(nil))
@@ -133,11 +122,26 @@ func (yh *KeyRoutingSessionHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnm
 	return nil
 }
 
-func updateOrCreateKeyRoutingSessions(confKMS *gnmitargetygot.Temp_KeyRoutingSessions, ekmsClient etsiqkdnclient.EkmsClient) error {
+func (yh *KeyRoutingSessionHandler) updateOrCreateKeyRoutingSessions(ekmsClient etsiqkdnclient.EkmsClient) ([]*gnmi.Notification, error) {
+	yh.Config.Lock()
+	defer yh.Config.Unlock()
+
+	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
+	if err != nil {
+		return nil, err
+	}
+
+	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
+	if !ok {
+		return nil, fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
+	}
+
+	confKeyRoutingSessions := newConfig.GetOrCreateKeyRoutingSessions()
+
 	ekmsRoutingTable := ekmsClient.Ekms().RoutingTableDeepCopy()
 
 	for _, route := range ekmsRoutingTable {
-		confTempRoutingSession := confKMS.GetOrCreateRoutingSessions(route.PathId.String())
+		confTempRoutingSession := confKeyRoutingSessions.GetOrCreateRoutingSessions(route.PathId.String())
 
 		if route.Previous != nil {
 			confPrevHop := confTempRoutingSession.GetOrCreatePrevHop()
@@ -174,5 +178,17 @@ func updateOrCreateKeyRoutingSessions(confKMS *gnmitargetygot.Temp_KeyRoutingSes
 		// TODO: add operation status
 	}
 
-	return nil
+	//validate struct
+	if err := newConfig.Validate(); err != nil {
+		return nil, err
+	}
+
+	notifications, err := ygot.DiffWithAtomic(yh.Config.Data, newConfig)
+	if err != nil {
+		return nil, err
+	}
+
+	yh.Config.Data = newConfig
+
+	return notifications, nil
 }
diff --git a/ekms/handlers/danet/kmsHandler.go b/ekms/handlers/danet/kmsHandler.go
index 84735acc099bd03e954fdc9ad267236c7016e489..e8a2e3f05570724e9551d29fae347a04b9abfeb5 100644
--- a/ekms/handlers/danet/kmsHandler.go
+++ b/ekms/handlers/danet/kmsHandler.go
@@ -3,6 +3,7 @@ package danet
 import (
 	"fmt"
 
+	"code.fbi.h-da.de/danet/gnmi-target/handler"
 	"code.fbi.h-da.de/danet/quant/ekms/etsiqkdnclient"
 	gnmitargetygot "code.fbi.h-da.de/danet/quant/ekms/model"
 	"github.com/openconfig/gnmi/proto/gnmi"
@@ -10,40 +11,28 @@ import (
 )
 
 type KmsHandler struct {
-	name       string
-	paths      map[string]struct{}
+	handler.DefaultPathHandler
 	ekmsClient etsiqkdnclient.EkmsClient
 }
 
 func NewKmsHandler(client etsiqkdnclient.EkmsClient) *KmsHandler {
 	return &KmsHandler{
-		name: "kms-handler",
-		paths: map[string]struct{}{
-			"/kms": {},
+		DefaultPathHandler: handler.DefaultPathHandler{
+			Name: "kms-handler",
+			Paths: map[string]struct{}{
+				"/kms": {},
+			},
 		},
 		ekmsClient: client,
 	}
 }
 
-func (yh *KmsHandler) Name() string {
-	return yh.name
-}
-
-func (yh *KmsHandler) Paths() map[string]struct{} {
-	return yh.paths
-}
-
-func (yh *KmsHandler) Init(c ygot.ValidatedGoStruct) error {
-	config, ok := c.(*gnmitargetygot.Gnmitarget)
-	if !ok {
-		return fmt.Errorf("failed type assertion for newConfig %T", (*gnmitargetygot.Gnmitarget)(nil))
-	}
-
-	// Create ygot structs for the kms
-	confEkms := config.GetOrCreateKms()
+func (yh *KmsHandler) Init(config *handler.Config, publishToSubsFunc func([]*gnmi.Notification) error) error {
+	yh.Config = config
+	yh.PublishToSubs = publishToSubsFunc
 
 	// Fill out the known fields in the ygot structs
-	err := updateOrCreateKMS(confEkms, yh.ekmsClient)
+	_, err := yh.updateOrCreateKMS(yh.ekmsClient)
 	if err != nil {
 		return err
 	}
@@ -56,7 +45,22 @@ func (yh *KmsHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update) erro
 	return nil
 }
 
-func updateOrCreateKMS(confKMS *gnmitargetygot.Temp_Kms, ekmsClient etsiqkdnclient.EkmsClient) error {
+func (yh *KmsHandler) updateOrCreateKMS(ekmsClient etsiqkdnclient.EkmsClient) ([]*gnmi.Notification, error) {
+	yh.Config.Lock()
+	defer yh.Config.Unlock()
+
+	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
+	if err != nil {
+		return nil, err
+	}
+
+	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
+	if !ok {
+		return nil, fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
+	}
+
+	confKMS := newConfig.GetOrCreateKms()
+
 	confKMS.KmsId = ygot.String(ekmsClient.ID().String())
 
 	confVersionInfo := confKMS.GetOrCreateVersionInformation()
@@ -64,5 +68,17 @@ func updateOrCreateKMS(confKMS *gnmitargetygot.Temp_Kms, ekmsClient etsiqkdnclie
 	confVersionInfo.HwVersion = ygot.String(ekmsClient.Version().HardwareVersion())
 	confVersionInfo.SwVersion = ygot.String(ekmsClient.Version().SoftwareVersion())
 
-	return nil
+	//validate struct
+	if err := newConfig.Validate(); err != nil {
+		return nil, err
+	}
+
+	notifications, err := ygot.DiffWithAtomic(yh.Config.Data, newConfig)
+	if err != nil {
+		return nil, err
+	}
+
+	yh.Config.Data = newConfig
+
+	return notifications, nil
 }
diff --git a/ekms/handlers/danet/peerHandler.go b/ekms/handlers/danet/peerHandler.go
index 1a22e2753c53a186f98be3ecc0d230b73df538fb..acf1a87e4e5c43218e2e3a73d6d70511da3a5009 100644
--- a/ekms/handlers/danet/peerHandler.go
+++ b/ekms/handlers/danet/peerHandler.go
@@ -3,6 +3,7 @@ package danet
 import (
 	"fmt"
 
+	"code.fbi.h-da.de/danet/gnmi-target/handler"
 	"code.fbi.h-da.de/danet/quant/ekms/etsiqkdnclient"
 	"code.fbi.h-da.de/danet/quant/ekms/internal/kms"
 	"code.fbi.h-da.de/danet/quant/ekms/internal/kms/event"
@@ -13,36 +14,26 @@ import (
 )
 
 type PeerHandler struct {
-	name       string
-	paths      map[string]struct{}
+	handler.DefaultPathHandler
 	ekmsClient etsiqkdnclient.EkmsClient
 	events     <-chan event.Event
 }
 
 func NewPeerHandler(client etsiqkdnclient.EkmsClient) *PeerHandler {
 	return &PeerHandler{
-		name: "kms-handler",
-		paths: map[string]struct{}{
-			// TODO:change to right path
-			"kms-peers": {},
+		DefaultPathHandler: handler.DefaultPathHandler{
+			Name: "kms-peer-handler",
+			Paths: map[string]struct{}{
+				"/kms-peers": {},
+			},
 		},
 		ekmsClient: client,
 	}
 }
 
-func (yh *PeerHandler) Name() string {
-	return yh.name
-}
-
-func (yh *PeerHandler) Paths() map[string]struct{} {
-	return yh.paths
-}
-
-func (yh *PeerHandler) Init(c ygot.ValidatedGoStruct) error {
-	config, ok := c.(*gnmitargetygot.Gnmitarget)
-	if !ok {
-		return fmt.Errorf("failed type assertion for newConfig %T", (*gnmitargetygot.Gnmitarget)(nil))
-	}
+func (yh *PeerHandler) Init(config *handler.Config, publishToSubsFunc func([]*gnmi.Notification) error) error {
+	yh.Config = config
+	yh.PublishToSubs = publishToSubsFunc
 
 	var err error
 	yh.events, err = yh.ekmsClient.Ekms().EventBus().Subscribe(event.PEER)
@@ -50,11 +41,8 @@ func (yh *PeerHandler) Init(c ygot.ValidatedGoStruct) error {
 		return err
 	}
 
-	// Create ygot structs for the kms
-	confPeerTable := config.GetOrCreateKmsPeerTable()
-
 	// Fill out the known fields in the ygot structs
-	err = updateOrCreatePeerTable(confPeerTable, yh.ekmsClient)
+	_, err = yh.updateOrCreatePeerTable(yh.ekmsClient)
 	if err != nil {
 		return err
 	}
@@ -65,8 +53,15 @@ func (yh *PeerHandler) Init(c ygot.ValidatedGoStruct) error {
 			select {
 			case <-yh.events:
 				log.Println("Update for KMSPeer.")
-				if err := updateOrCreatePeerTable(confPeerTable, yh.ekmsClient); err != nil {
-					log.Println("Error within kmspeer update goroutine.")
+				//lock access for model
+				diff, err := yh.updateOrCreatePeerTable(yh.ekmsClient)
+				if err != nil {
+					log.Errorf("Error within interface subscription goroutine; %v", err)
+					// TODO: check again
+					break
+				}
+				if err := yh.PublishToSubs(diff); err != nil {
+					log.Errorf("Error within interface subscription goroutine; %v", err)
 				}
 			}
 		}
@@ -80,11 +75,27 @@ func (yh *PeerHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update) err
 	return nil
 }
 
-func updateOrCreatePeerTable(confKMS *gnmitargetygot.Temp_KmsPeerTable, ekmsClient etsiqkdnclient.EkmsClient) error {
+func (yh *PeerHandler) updateOrCreatePeerTable(ekmsClient etsiqkdnclient.EkmsClient) ([]*gnmi.Notification, error) {
+	yh.Config.Lock()
+	defer yh.Config.Unlock()
+
+	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
+	if err != nil {
+		return nil, err
+	}
+
+	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
+	if !ok {
+		return nil, fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
+	}
+
+	// Create ygot structs for the kms
+	confKmsPeerTable := newConfig.GetOrCreateKmsPeerTable()
+
 	kmsPeers := ekmsClient.Ekms().PeersDeepCopy()
 
 	for _, peer := range kmsPeers {
-		confTempKmsPeer := confKMS.GetOrCreateKmsPeers(peer.GetKmsPeerId().String())
+		confTempKmsPeer := confKmsPeerTable.GetOrCreateKmsPeers(peer.GetKmsPeerId().String())
 		confTempPeerInformation := confTempKmsPeer.GetOrCreatePeerInformation()
 		confTempPeerAddress := confTempPeerInformation.GetOrCreatePeerAddress()
 
@@ -112,5 +123,17 @@ func updateOrCreatePeerTable(confKMS *gnmitargetygot.Temp_KmsPeerTable, ekmsClie
 		confTempPeerInformation.NegotiatedKeyLength = ygot.Uint64(256)
 	}
 
-	return nil
+	//validate struct
+	if err := newConfig.Validate(); err != nil {
+		return nil, err
+	}
+
+	notifications, err := ygot.DiffWithAtomic(yh.Config.Data, newConfig)
+	if err != nil {
+		return nil, err
+	}
+
+	yh.Config.Data = newConfig
+
+	return notifications, nil
 }
diff --git a/ekms/handlers/system/hostnameHandler.go b/ekms/handlers/system/hostnameHandler.go
index e03e5776fa92c793b8812583a06a3f953115b815..461319ce29f8a1a511348a75cda7febd2fe66a74 100644
--- a/ekms/handlers/system/hostnameHandler.go
+++ b/ekms/handlers/system/hostnameHandler.go
@@ -3,6 +3,7 @@ package system
 import (
 	"fmt"
 
+	"code.fbi.h-da.de/danet/gnmi-target/handler"
 	gnmitargetygot "code.fbi.h-da.de/danet/quant/ekms/model"
 	"code.fbi.h-da.de/danet/quant/ekms/osclient"
 	"github.com/openconfig/gnmi/proto/gnmi"
@@ -12,44 +13,35 @@ import (
 
 // HostnameHandler is the implementation of a gnmitarget.PathHandler.
 type HostnameHandler struct {
-	name     string
-	paths    map[string]struct{}
+	handler.DefaultPathHandler
 	osClient osclient.Osclient
 }
 
 func NewHostnameHandler() *HostnameHandler {
 	return &HostnameHandler{
-		name: "openconfig-hostname-handler",
-		paths: map[string]struct{}{
-			"/system/config/hostname": {},
+		DefaultPathHandler: handler.DefaultPathHandler{
+			Name: "openconfig-hostname-handler",
+			Paths: map[string]struct{}{
+				"/system/config/hostname": {},
+			},
 		},
 		osClient: osclient.NewOsClient(),
 	}
 }
 
-func (yh *HostnameHandler) Name() string {
-	return yh.name
-}
-
-func (yh *HostnameHandler) Paths() map[string]struct{} {
-	return yh.paths
-}
-
-func (yh *HostnameHandler) Init(c ygot.ValidatedGoStruct) error {
-	config, ok := c.(*gnmitargetygot.Gnmitarget)
-	if !ok {
-		return fmt.Errorf("failed type assertion for config %T", (*gnmitargetygot.Gnmitarget)(nil))
-	}
+func (yh *HostnameHandler) Init(config *handler.Config, publishToSubsFunc func([]*gnmi.Notification) error) error {
+	yh.Config = config
+	yh.PublishToSubs = publishToSubsFunc
 
-	confSystem := config.GetOrCreateSystem()
-	if err := updateOrCreateHostname(confSystem, yh.osClient); err != nil {
+	_, err := yh.updateOrCreateHostname(yh.osClient)
+	if err != nil {
 		return err
 	}
 	return nil
 }
 
 func (yh *HostnameHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update) error {
-	fmt.Println("Update request received for ", yh.name)
+	fmt.Println("Update request received for ", yh.Name)
 	config, ok := c.(*gnmitargetygot.Gnmitarget)
 	if !ok {
 		return fmt.Errorf("failed type assertion for config %T", (*gnmitargetygot.Gnmitarget)(nil))
@@ -71,19 +63,41 @@ func (yh *HostnameHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update)
 	return nil
 }
 
-func updateOrCreateHostname(confSystem *gnmitargetygot.OpenconfigSystem_System, os osclient.Osclient) error {
+func (yh *HostnameHandler) updateOrCreateHostname(os osclient.Osclient) ([]*gnmi.Notification, error) {
+	yh.Config.Lock()
+	defer yh.Config.Unlock()
+
+	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
+	if err != nil {
+		return nil, err
+	}
+
+	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
+	if !ok {
+		return nil, fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
+	}
+
+	confSystem := newConfig.GetOrCreateSystem()
+
 	if config := confSystem.GetOrCreateConfig(); config != nil {
 		h, err := os.GetHostname()
 		if err != nil {
-			return err
+			return nil, err
 		}
 		config.Hostname = &h
 	}
 
-	// validate struct
-	if err := confSystem.Validate(); err != nil {
-		return err
+	//validate struct
+	if err := newConfig.Validate(); err != nil {
+		return nil, err
 	}
 
-	return nil
+	notifications, err := ygot.DiffWithAtomic(yh.Config.Data, newConfig)
+	if err != nil {
+		return nil, err
+	}
+
+	yh.Config.Data = newConfig
+
+	return notifications, nil
 }
diff --git a/ekms/handlers/system/memoryHandler.go b/ekms/handlers/system/memoryHandler.go
index 5d1b9cc1c8de4325b2476a44228f737cd6e63fc9..adb09b43e396b0c67e39c72f27c30e0fc483f00e 100644
--- a/ekms/handlers/system/memoryHandler.go
+++ b/ekms/handlers/system/memoryHandler.go
@@ -3,6 +3,7 @@ package system
 import (
 	"fmt"
 
+	"code.fbi.h-da.de/danet/gnmi-target/handler"
 	gnmitargetygot "code.fbi.h-da.de/danet/quant/ekms/model"
 	"code.fbi.h-da.de/danet/quant/ekms/osclient"
 	"github.com/openconfig/gnmi/proto/gnmi"
@@ -11,58 +12,71 @@ import (
 
 // MemoryHandler is the implementation of a gnmitarget.PathHandler.
 type MemoryHandler struct {
-	name     string
-	paths    map[string]struct{}
+	handler.DefaultPathHandler
 	osClient osclient.Osclient
 }
 
 func NewMemoryHandler() *MemoryHandler {
 	return &MemoryHandler{
-		name: "openconfig-memory-handler",
-		paths: map[string]struct{}{
-			"/system/memory/state": {},
+		DefaultPathHandler: handler.DefaultPathHandler{
+			Name: "openconfig-memory-handler",
+			Paths: map[string]struct{}{
+				"/system/memory/state": {},
+			},
 		},
 		osClient: osclient.NewOsClient(),
 	}
 }
 
-func (yh *MemoryHandler) Name() string {
-	return yh.name
-}
-
-func (yh *MemoryHandler) Paths() map[string]struct{} {
-	return yh.paths
-}
+func (yh *MemoryHandler) Init(config *handler.Config, publishToSubsFunc func([]*gnmi.Notification) error) error {
+	yh.Config = config
+	yh.PublishToSubs = publishToSubsFunc
 
-func (yh *MemoryHandler) Init(c ygot.ValidatedGoStruct) error {
-	config, ok := c.(*gnmitargetygot.Gnmitarget)
-	if !ok {
-		return fmt.Errorf("failed type assertion for config %T", (*gnmitargetygot.Gnmitarget)(nil))
-	}
-
-	confSystem := config.GetOrCreateSystem()
-	if err := updateOrCreateMemory(confSystem, yh.osClient); err != nil {
+	_, err := yh.updateOrCreateMemory(yh.osClient)
+	if err != nil {
 		return err
 	}
 	return nil
 }
 
 func (yh *MemoryHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update) error {
-	fmt.Println("Update request received for ", yh.name)
+	fmt.Println("Update request received for ", yh.Name)
 	return nil
 }
 
-func updateOrCreateMemory(confSystem *gnmitargetygot.OpenconfigSystem_System, os osclient.Osclient) error {
+func (yh *MemoryHandler) updateOrCreateMemory(os osclient.Osclient) ([]*gnmi.Notification, error) {
+	yh.Config.Lock()
+	defer yh.Config.Unlock()
+
+	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
+	if err != nil {
+		return nil, err
+	}
+
+	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
+	if !ok {
+		return nil, fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
+	}
+
+	confSystem := newConfig.GetOrCreateSystem()
+
 	if memory := confSystem.GetOrCreateMemory(); memory != nil {
 		memory.GetOrCreateState().Physical = ygot.Uint64(os.GetTotalMemory())
 		memory.GetOrCreateState().Free = ygot.Uint64(os.GetFreeMemory())
 		memory.GetOrCreateState().Used = ygot.Uint64(os.GetUsedMemory())
 	}
 
-	// validate struct
-	if err := confSystem.Validate(); err != nil {
-		return err
+	//validate struct
+	if err := newConfig.Validate(); err != nil {
+		return nil, err
 	}
 
-	return nil
+	notifications, err := ygot.DiffWithAtomic(yh.Config.Data, newConfig)
+	if err != nil {
+		return nil, err
+	}
+
+	yh.Config.Data = newConfig
+
+	return notifications, nil
 }
diff --git a/ekms/handlers/system/motdHandler.go b/ekms/handlers/system/motdHandler.go
deleted file mode 100644
index 958c290b9b726b5c833e93a87d784ff9791361f2..0000000000000000000000000000000000000000
--- a/ekms/handlers/system/motdHandler.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package system
-
-import (
-	"fmt"
-
-	gnmitargetygot "code.fbi.h-da.de/danet/quant/ekms/model"
-	"code.fbi.h-da.de/danet/quant/ekms/osclient"
-	"github.com/openconfig/gnmi/proto/gnmi"
-	"github.com/openconfig/ygot/ygot"
-	"github.com/sirupsen/logrus"
-)
-
-// MotdHandler is the implementation of a gnmitarget.PathHandler.
-type MotdHandler struct {
-	name     string
-	paths    map[string]struct{}
-	osClient osclient.Osclient
-}
-
-func NewMotdHandler() *MotdHandler {
-	return &MotdHandler{
-		name: "openconfig-motd-handler",
-		paths: map[string]struct{}{
-			"/system/config/motd-banner": {},
-		},
-		osClient: osclient.NewOsClient(),
-	}
-}
-
-func (yh *MotdHandler) Name() string {
-	return yh.name
-}
-
-func (yh *MotdHandler) Paths() map[string]struct{} {
-	return yh.paths
-}
-
-func (yh *MotdHandler) Init(c ygot.ValidatedGoStruct) error {
-	config, ok := c.(*gnmitargetygot.Gnmitarget)
-	if !ok {
-		return fmt.Errorf("failed type assertion for config %T", (*gnmitargetygot.Gnmitarget)(nil))
-	}
-
-	confSystem := config.GetOrCreateSystem()
-	if err := updateOrCreateMotd(confSystem, yh.osClient); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (yh *MotdHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update) error {
-	fmt.Println("Update request received for ", yh.name)
-	config, ok := c.(*gnmitargetygot.Gnmitarget)
-	if !ok {
-		return fmt.Errorf("failed type assertion for config %T", (*gnmitargetygot.Gnmitarget)(nil))
-	}
-
-	system := config.GetSystem()
-
-	if system != nil {
-		if config := system.GetOrCreateConfig(); config != nil {
-			if motd := config.GetMotdBanner(); motd != "" {
-				err := yh.osClient.SetMotd(motd)
-				if err != nil {
-					logrus.Debug("Failed to set motd banner: ", err)
-					return err
-				}
-			}
-		}
-	}
-	return nil
-}
-
-func updateOrCreateMotd(confSystem *gnmitargetygot.OpenconfigSystem_System, os osclient.Osclient) error {
-	if config := confSystem.GetOrCreateConfig(); config != nil {
-		motd, err := os.GetMotd()
-		if err != nil {
-			return err
-		}
-		config.MotdBanner = ygot.String(motd)
-	}
-
-	// validate struct
-	if err := confSystem.Validate(); err != nil {
-		return err
-	}
-
-	return nil
-}
diff --git a/ekms/handlers/system/stateHandler.go b/ekms/handlers/system/stateHandler.go
index 81e9973155d92369728914ada2bb48559f1752e2..461a2a5ae8e4ef917f7e6b8a058e4e574f33572a 100644
--- a/ekms/handlers/system/stateHandler.go
+++ b/ekms/handlers/system/stateHandler.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"time"
 
+	"code.fbi.h-da.de/danet/gnmi-target/handler"
 	gnmitargetygot "code.fbi.h-da.de/danet/quant/ekms/model"
 	"code.fbi.h-da.de/danet/quant/ekms/osclient"
 	"github.com/openconfig/gnmi/proto/gnmi"
@@ -13,53 +14,59 @@ import (
 
 // StateHandler is the implementation of a gnmitarget.PathHandler.
 type StateHandler struct {
-	name     string
-	paths    map[string]struct{}
+	handler.DefaultPathHandler
 	osClient osclient.Osclient
 }
 
 func NewStateHandler() *StateHandler {
 	return &StateHandler{
-		name: "openconfig-memory-handler",
-		paths: map[string]struct{}{
-			"/system/state": {},
+		DefaultPathHandler: handler.DefaultPathHandler{
+			Name: "openconfig-memory-handler",
+			Paths: map[string]struct{}{
+				"/system/state": {},
+			},
 		},
 		osClient: osclient.NewOsClient(),
 	}
 }
 
-func (yh *StateHandler) Name() string {
-	return yh.name
-}
-
-func (yh *StateHandler) Paths() map[string]struct{} {
-	return yh.paths
-}
+func (yh *StateHandler) Init(config *handler.Config, publishToSubsFunc func([]*gnmi.Notification) error) error {
+	yh.Config = config
+	yh.PublishToSubs = publishToSubsFunc
 
-func (yh *StateHandler) Init(c ygot.ValidatedGoStruct) error {
-	config, ok := c.(*gnmitargetygot.Gnmitarget)
-	if !ok {
-		return fmt.Errorf("failed type assertion for config %T", (*gnmitargetygot.Gnmitarget)(nil))
-	}
-
-	confSystem := config.GetOrCreateSystem()
-	if err := updateOrCreateState(confSystem, yh.osClient); err != nil {
+	_, err := yh.updateOrCreateState(yh.osClient)
+	if err != nil {
 		return err
 	}
 	return nil
 }
 
 func (yh *StateHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update) error {
-	fmt.Println("Update request received for ", yh.name)
+	fmt.Println("Update request received for ", yh.Name)
 	return nil
 }
 
-func updateOrCreateState(confSystem *gnmitargetygot.OpenconfigSystem_System, os osclient.Osclient) error {
+func (yh *StateHandler) updateOrCreateState(os osclient.Osclient) ([]*gnmi.Notification, error) {
+	yh.Config.Lock()
+	defer yh.Config.Unlock()
+
+	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
+	if err != nil {
+		return nil, err
+	}
+
+	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
+	if !ok {
+		return nil, fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
+	}
+
+	confSystem := newConfig.GetOrCreateSystem()
+
 	if state := confSystem.GetOrCreateState(); state != nil {
 		state.CurrentDatetime = ygot.String(time.Now().Format(time.RFC3339))
 		bootTime, err := gopshost.BootTime()
 		if err != nil {
-			return err
+			return nil, err
 		}
 		state.BootTime = ygot.Uint64(bootTime)
 
@@ -69,10 +76,17 @@ func updateOrCreateState(confSystem *gnmitargetygot.OpenconfigSystem_System, os
 		state.SoftwareVersion = ygot.String(osVersion)
 	}
 
-	// validate struct
-	if err := confSystem.Validate(); err != nil {
-		return err
+	//validate struct
+	if err := newConfig.Validate(); err != nil {
+		return nil, err
 	}
 
-	return nil
+	notifications, err := ygot.DiffWithAtomic(yh.Config.Data, newConfig)
+	if err != nil {
+		return nil, err
+	}
+
+	yh.Config.Data = newConfig
+
+	return notifications, nil
 }
diff --git a/ekms/handlers/system/systemHandler.go b/ekms/handlers/system/systemHandler.go
index 932594bc883e82a124b5fa69ec3ebad489b985ca..69b6eea1a2cf6243abea9bfc4e077d03bf6fe87b 100644
--- a/ekms/handlers/system/systemHandler.go
+++ b/ekms/handlers/system/systemHandler.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"strings"
 
+	"code.fbi.h-da.de/danet/gnmi-target/handler"
 	gnmitargetygot "code.fbi.h-da.de/danet/quant/ekms/model"
 	"code.fbi.h-da.de/danet/quant/ekms/osclient"
 	"github.com/openconfig/gnmi/proto/gnmi"
@@ -12,52 +13,58 @@ import (
 
 // SystemHandler is the implementation of a gnmitarget.PathHandler.
 type SystemHandler struct {
-	name     string
-	paths    map[string]struct{}
+	handler.DefaultPathHandler
 	osClient osclient.Osclient
 }
 
 func NewSystemHandler() *SystemHandler {
 	return &SystemHandler{
-		name: "openconfig-system-handler",
-		paths: map[string]struct{}{
-			"/system": {},
+		DefaultPathHandler: handler.DefaultPathHandler{
+			Name: "openconfig-system-handler",
+			Paths: map[string]struct{}{
+				"/system": {},
+			},
 		},
 		osClient: osclient.NewOsClient(),
 	}
 }
 
-func (yh *SystemHandler) Name() string {
-	return yh.name
-}
-
-func (yh *SystemHandler) Paths() map[string]struct{} {
-	return yh.paths
-}
+func (yh *SystemHandler) Init(config *handler.Config, publishToSubsFunc func([]*gnmi.Notification) error) error {
+	yh.Config = config
+	yh.PublishToSubs = publishToSubsFunc
 
-func (yh *SystemHandler) Init(c ygot.ValidatedGoStruct) error {
-	config, ok := c.(*gnmitargetygot.Gnmitarget)
-	if !ok {
-		return fmt.Errorf("failed type assertion for config %T", (*gnmitargetygot.Gnmitarget)(nil))
-	}
-
-	confSystem := config.GetOrCreateSystem()
-	if err := updateOrCreateSystem(confSystem, yh.osClient); err != nil {
+	_, err := yh.updateOrCreateSystem(yh.osClient)
+	if err != nil {
 		return err
 	}
 	return nil
 }
 
 func (yh *SystemHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update) error {
-	fmt.Println("Update request received for ", yh.name)
+	fmt.Println("Update request received for ", yh.Name)
 	return nil
 }
 
-func updateOrCreateSystem(confSystem *gnmitargetygot.OpenconfigSystem_System, os osclient.Osclient) error {
+func (yh *SystemHandler) updateOrCreateSystem(os osclient.Osclient) ([]*gnmi.Notification, error) {
+	yh.Config.Lock()
+	defer yh.Config.Unlock()
+
+	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
+	if err != nil {
+		return nil, err
+	}
+
+	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
+	if !ok {
+		return nil, fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
+	}
+
+	confSystem := newConfig.GetOrCreateSystem()
+
 	if config := confSystem.GetOrCreateConfig(); config != nil {
 		domain, err := os.GetDomainName()
 		if err != nil {
-			return err
+			return nil, err
 		}
 		config.DomainName = ygot.String(domain)
 	}
@@ -68,10 +75,17 @@ func updateOrCreateSystem(confSystem *gnmitargetygot.OpenconfigSystem_System, os
 		}
 	}
 
-	// validate struct
-	if err := confSystem.Validate(); err != nil {
-		return err
+	//validate struct
+	if err := newConfig.Validate(); err != nil {
+		return nil, err
 	}
 
-	return nil
+	notifications, err := ygot.DiffWithAtomic(yh.Config.Data, newConfig)
+	if err != nil {
+		return nil, err
+	}
+
+	yh.Config.Data = newConfig
+
+	return notifications, nil
 }
diff --git a/ekms/internal/akmsCkmsServer/akmsCkmsServer.go b/ekms/internal/akmsCkmsServer/akmsCkmsServer.go
index 546e3bf0f9755b121b0833e68156ef80dd6e2428..4dc129edf1b0c51fcb432892b7bad287a2c55174 100644
--- a/ekms/internal/akmsCkmsServer/akmsCkmsServer.go
+++ b/ekms/internal/akmsCkmsServer/akmsCkmsServer.go
@@ -5,6 +5,8 @@ import (
 	"net/http"
 
 	"code.fbi.h-da.de/danet/quant/ekms/internal/kms"
+	"code.fbi.h-da.de/danet/quant/ekms/internal/kms/event"
+	"github.com/google/uuid"
 	"github.com/sirupsen/logrus"
 )
 
@@ -61,13 +63,32 @@ func ksaReqHandler(ekms *kms.EKMS) http.HandlerFunc {
 		logrus.Infof("received KSA key request for receiving CKMS %s, request ID %s, and key properties %v",
 			kmsKeyRequest.ReceivingCKMSID, kmsKeyRequest.RequestID, kmsKeyRequest.KeyProperties)
 
-		err = ekms.GenerateAndSendKSAKey(kmsKeyRequest.ReceivingCKMSID, kmsKeyRequest.RequestID, kmsKeyRequest.KeyProperties.Number)
+		pathId := uuid.New()
+
+		receiverChan, err := ekms.Receiver.RequestReceiverChannel(pathId)
+		if err != nil {
+			http.Error(w, err.Error(), http.StatusInternalServerError)
+		}
+
+		err = ekms.EventBus().Publish(event.NewCreateRouteEvent(pathId.String(), kmsKeyRequest.ReceivingCKMSID))
 		if err != nil {
 			http.Error(w, err.Error(), http.StatusInternalServerError)
-			logrus.Errorf("error generating and sending KSA key: %s", err)
+			logrus.Errorf("Failed sending a create route request: %s", err)
 			return
 		}
 
+		go func() {
+			select {
+			case <-receiverChan:
+				err = ekms.GenerateAndSendKSAKey(kmsKeyRequest.ReceivingCKMSID, pathId, kmsKeyRequest.RequestID, kmsKeyRequest.KeyProperties.Number)
+				if err != nil {
+					http.Error(w, err.Error(), http.StatusInternalServerError)
+					logrus.Errorf("error generating and sending KSA key: %s", err)
+					return
+				}
+			}
+		}()
+
 		logrus.Info("requested all keys")
 		w.WriteHeader(http.StatusNoContent)
 	}
diff --git a/ekms/internal/kms/event/bus.go b/ekms/internal/kms/event/bus.go
index 301b883b09fa8d71d10cfae043415fc5adad0e80..a1c297ba66d0427dde6e379d8a8b876d469bba46 100644
--- a/ekms/internal/kms/event/bus.go
+++ b/ekms/internal/kms/event/bus.go
@@ -30,6 +30,7 @@ func (b *EventBus) Subscribe(topic Topic) (<-chan Event, error) {
 	return newSubChan, nil
 }
 
+// TODO: check the functionality of this method.
 func (b *EventBus) Publish(event Event) error {
 	subs, ok := b.subscribers[event.Topic()]
 	if !ok {
diff --git a/ekms/internal/kms/event/event.go b/ekms/internal/kms/event/event.go
index 43b3da591ca433d7931a70679965a56b29384a1d..b99faee99ccabaf0ca246dff53294935ce7961ac 100644
--- a/ekms/internal/kms/event/event.go
+++ b/ekms/internal/kms/event/event.go
@@ -8,6 +8,7 @@ const (
 	PEER Topic = iota
 	ROUTE
 	QUANTUM_MODULE
+	CREATE_ROUTE
 )
 
 // Event ...
@@ -16,6 +17,30 @@ type Event interface {
 	Time() time.Time
 }
 
+type CreateRouteEvent struct {
+	EventTopic   Topic
+	Timestamp    time.Time
+	KmsPathId    string
+	RemoteUkmsId string
+}
+
+func NewCreateRouteEvent(kmsPathId, remoteUkmsId string) *CreateRouteEvent {
+	return &CreateRouteEvent{
+		EventTopic:   CREATE_ROUTE,
+		Timestamp:    time.Now(),
+		KmsPathId:    kmsPathId,
+		RemoteUkmsId: remoteUkmsId,
+	}
+}
+
+func (e *CreateRouteEvent) Topic() Topic {
+	return e.EventTopic
+}
+
+func (e *CreateRouteEvent) Time() time.Time {
+	return e.Timestamp
+}
+
 type PeerEvent struct {
 	EventTopic Topic
 	Timestamp  time.Time
diff --git a/ekms/internal/kms/kms.go b/ekms/internal/kms/kms.go
index 91325426a39ef6b72fc47f93f7ad2c2d4fe6ea10..8c7157e63aad28fdc8384be7cbc9c560611e1518 100644
--- a/ekms/internal/kms/kms.go
+++ b/ekms/internal/kms/kms.go
@@ -77,6 +77,7 @@ type EKMS struct {
 	supportedKeyLengths map[BitKeyLength]bool
 	eventBus            *event.EventBus
 	ckmsAkmsClient      akmsCkmsClient.CkmsAkmsClient
+	Receiver            *Receiver
 }
 
 // Will keep information about the quantum elements that this EKMS is talking to
@@ -122,6 +123,9 @@ func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel lo
 		supportedKeyLengths: make(map[BitKeyLength]bool),
 		eventBus:            event.NewEventBus(),
 		ckmsAkmsClient:      ckmsAkmsClient,
+		Receiver: &Receiver{
+			receivers: make(map[uuid.UUID]chan<- struct{}),
+		},
 	}
 
 	createdEKMS.supportedKeyLengths[BitKeyLen256] = true
@@ -271,11 +275,6 @@ func (kms *EKMS) AssignForwardingRoute(pId, pHop, nHop string, remoteKMS *Remote
 		kms.PKStoreMutex.Unlock()
 	}
 
-	err = kms.eventBus.Publish(event.NewRouteEvent())
-	if err != nil {
-		log.Error(err)
-	}
-
 	log.Debug("Current PKSTORE: ", kms.PKStore)
 
 	return nil
@@ -323,7 +322,7 @@ func (kms *EKMS) GetRemoteKMS(remoteKMSId string) (*RemoteKMS, error) {
 }
 
 // NOTE: address/remoteid still have to decide.
-func (kms *EKMS) GenerateAndSendKSAKey(remoteKMSId string, requestId string, number int) error {
+func (kms *EKMS) GenerateAndSendKSAKey(remoteKMSId string, pathId uuid.UUID, requestId string, number int) error {
 	if number < 1 {
 		log.Errorf("number must be positive and at least 1, provided: %d\n", number)
 		return fmt.Errorf("number must be positive and at least 1, provided: %d", number)
@@ -336,7 +335,7 @@ func (kms *EKMS) GenerateAndSendKSAKey(remoteKMSId string, requestId string, num
 		return err
 	}
 
-	keyId, pk, err := kms.GetRandomItemFromPKStore(remoteKMSId)
+	pk, err := kms.GetSpecificPK(remoteKMSId, pathId)
 	if err != nil {
 		log.Error(err)
 		return err
@@ -393,7 +392,7 @@ func (kms *EKMS) GenerateAndSendKSAKey(remoteKMSId string, requestId string, num
 	ctx = metadata.NewOutgoingContext(ctx, md)
 	defer cancel()
 	_, err = remoteClient.KeyDelivery(ctx, &pbIC.KeyDeliveryRequest{
-		KeyId:     keyId.String(),
+		KeyId:     pk.Id.String(),
 		RequestId: requestId,
 		KmsId:     kms.kmsUUID.String(),
 		// TODO: change if multiple keys are generated
diff --git a/ekms/internal/kms/kmsintercom.go b/ekms/internal/kms/kmsintercom.go
index 74905be65fad12d6463b53a54a455155bf59d73a..718816d622a2d3f84ffff34995f23f98a261582c 100644
--- a/ekms/internal/kms/kmsintercom.go
+++ b/ekms/internal/kms/kmsintercom.go
@@ -129,11 +129,11 @@ func (s *kmsTalkerServer) SyncKeyIdsForBulk(ctx context.Context, in *pb.SyncKeyI
 	}
 
 	eqm.rawBulkKeysMutex.Lock()
+	defer eqm.rawBulkKeysMutex.Unlock()
 	bulk, ok := eqm.rawBulkKeys[in.GetBulkId()]
 	if !ok {
 		return nil, status.Errorf(codes.Internal, "bulk key with id: %d not found", in.GetBulkId())
 	}
-	eqm.rawBulkKeysMutex.Unlock()
 
 	eqm.keyStore = NewKmsKeyStore(256)
 	_, keyData, err := eqm.KeyChopper(bulk, in.GetKeyId())
@@ -145,18 +145,18 @@ func (s *kmsTalkerServer) SyncKeyIdsForBulk(ctx context.Context, in *pb.SyncKeyI
 		eqm.keyStore.addKey(keyId, key)
 	}
 
-	eqm.rawBulkKeysMutex.Lock()
 	delete(eqm.rawBulkKeys, in.GetBulkId())
-	eqm.rawBulkKeysMutex.Unlock()
 
 	// update the peer status to up
 	peer.peerStatus = KmsPeerUp
 	// Send notification about change
 	if peer.eventBus != nil {
-		err := peer.eventBus.Publish(event.NewPeerEvent(peer.tcpSocketStr))
-		if err != nil {
-			log.Error(err)
-		}
+		go func() {
+			err := peer.eventBus.Publish(event.NewPeerEvent(peer.tcpSocketStr))
+			if err != nil {
+				log.Error(err)
+			}
+		}()
 	}
 
 	return &pb.SyncKeyIdsForBulkResponse{
@@ -259,40 +259,30 @@ func (s *kmsTalkerServer) KeyForwarding(ctx context.Context, in *pb.KeyForwardin
 		keys, ok := s.eKMS.PKStore[route.RemoteKMS.Id]
 		if !ok {
 			s.eKMS.PKStore[route.RemoteKMS.Id] = map[uuid.UUID]*PlatformKey{
-				keyID: {
+				pathId: {
 					Id:        keyID,
 					Value:     decryptedKey,
 					ProcessId: in.GetProcessId(),
 				},
 			}
 		} else {
-			keys[keyID] = &PlatformKey{
+			keys[pathId] = &PlatformKey{
 				Id:        keyID,
 				Value:     decryptedKey,
 				ProcessId: in.GetProcessId(),
 			}
 		}
 
+		// push to channel key received
+		if err := s.eKMS.Receiver.InformReceiver(pathId); err != nil {
+			log.Debugf("%s", err)
+			return nil, status.Errorf(codes.Internal, "%s", err)
+		}
+
 		log.Debug("Current PKSTORE: ", s.eKMS.PKStore)
 		s.eKMS.PKStoreMutex.Unlock()
 	}
 
-	//// NOTE: For demo purpose only
-	//json, err := json.Marshal(KMSInfo{
-	//	Name:             s.eKMS.kmsName,
-	//	EncryptedMessage: in.Payload,
-	//	DecryptedMessage: string(decryptedPayload),
-	//	Key:              base64.StdEncoding.EncodeToString(decryptKey.key),
-	//})
-	//if err != nil {
-	//	log.Println("Failed to marshal: ", err)
-	//}
-
-	//err = sendKmsInfoMessage("http://172.20.10.21:4000/kmsinfo", json)
-	//if err != nil {
-	//	log.Println("Failed to send KMS info message: ", err)
-	//}
-
 	return &pb.KeyForwardingResponse{Timestamp: time.Now().Unix()}, nil
 }
 
diff --git a/ekms/internal/kms/module.go b/ekms/internal/kms/module.go
index 59efcaa336b6292ec22f67e2ebf71b00b03b0634..212f964d99381e233e7a108ac8e5e27cbfc10c31 100644
--- a/ekms/internal/kms/module.go
+++ b/ekms/internal/kms/module.go
@@ -121,10 +121,12 @@ func (eqe *EmulatedQuantumModule) Sync() error {
 	eqe.peer.peerStatus = KmsPeerUp
 	// Send notification about change
 	if eqe.peer.eventBus != nil {
-		err := eqe.peer.eventBus.Publish(event.NewPeerEvent(eqe.peer.tcpSocketStr))
-		if err != nil {
-			log.Error(err)
-		}
+		go func() {
+			err := eqe.peer.eventBus.Publish(event.NewPeerEvent(eqe.peer.tcpSocketStr))
+			if err != nil {
+				log.Error(err)
+			}
+		}()
 	}
 
 	return nil
diff --git a/ekms/internal/kms/receiver.go b/ekms/internal/kms/receiver.go
new file mode 100644
index 0000000000000000000000000000000000000000..225237272590755fff218a009a7069b470f040ae
--- /dev/null
+++ b/ekms/internal/kms/receiver.go
@@ -0,0 +1,35 @@
+package kms
+
+import (
+	"fmt"
+	"sync"
+
+	"github.com/google/uuid"
+)
+
+type Receiver struct {
+	mu        sync.RWMutex
+	receivers map[uuid.UUID]chan<- struct{}
+}
+
+func (r *Receiver) RequestReceiverChannel(pathId uuid.UUID) (<-chan struct{}, error) {
+	newSubChan := make(chan struct{})
+
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	r.receivers[pathId] = newSubChan
+
+	return newSubChan, nil
+}
+
+func (r *Receiver) InformReceiver(pathId uuid.UUID) error {
+	r.mu.RLock()
+	defer r.mu.RUnlock()
+
+	if receiver, ok := r.receivers[pathId]; ok {
+		receiver <- struct{}{}
+	} else {
+		return fmt.Errorf("There are no active subscribers for pathId: %s", pathId)
+	}
+	return nil
+}
diff --git a/go.mod b/go.mod
index aa9005ecd10866340040c74c664cd26362b6a143..d4e9c308f2d81695558d0894e784b7d1dd5d2eda 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module code.fbi.h-da.de/danet/quant
 go 1.22
 
 require (
-	code.fbi.h-da.de/danet/gnmi-target v0.0.0-20240216142748-f55e5e2a1800
+	code.fbi.h-da.de/danet/gnmi-target v0.0.0-20240402114917-f5441059d9a3
 	code.fbi.h-da.de/danet/quipsec/gen/go/quipsec v0.0.0-20231207135002-06d40645e073
 	github.com/google/uuid v1.6.0
 	github.com/gorilla/mux v1.8.1
diff --git a/go.sum b/go.sum
index 6b61406041a7e80a4032088b9b00a422c22ad5c2..5329a27300c8d6bd2bd2f35b9f54d8d56ed9139c 100644
--- a/go.sum
+++ b/go.sum
@@ -4,6 +4,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 code.fbi.h-da.de/danet/gnmi-target v0.0.0-20240216142748-f55e5e2a1800 h1:u2Hj0MBV6oK/FYwIXwju8wb1Qh9b5gKYIZXgWAi2+gY=
 code.fbi.h-da.de/danet/gnmi-target v0.0.0-20240216142748-f55e5e2a1800/go.mod h1:N1AxQEtUEmr3EscCgl3sDfIYWMfiLloA/+qf2u86uRU=
+code.fbi.h-da.de/danet/gnmi-target v0.0.0-20240402114917-f5441059d9a3 h1:dPckYMg+NE2VrlNTRmh4tiIW7R3eE0D6UcSfNfj5wBg=
+code.fbi.h-da.de/danet/gnmi-target v0.0.0-20240402114917-f5441059d9a3/go.mod h1:C4IbVg/BycbBXbhFn3JOUjrUk1NZwXybNC4e0bNhFHk=
 code.fbi.h-da.de/danet/quipsec/gen/go/quipsec v0.0.0-20231207135002-06d40645e073 h1:SFFYqhG0UkPXPnEoX3ZBhyLbn8Rxjxy7hd15BMW+pQo=
 code.fbi.h-da.de/danet/quipsec/gen/go/quipsec v0.0.0-20231207135002-06d40645e073/go.mod h1:lPCd19Jk8aL5B3xSk+h6y5sziXVPqyCXgO7dILvJFfQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
diff --git a/integration-tests/code/getKSAKeyTest/getKSA_key_test.go b/integration-tests/code/getKSAKeyTest/getKSA_key_test.go
index 405796a4d3b4097a717d8c30b4df5937ef98be7a..20db70570cacc26716745348ebe0597c64435e41 100644
--- a/integration-tests/code/getKSAKeyTest/getKSA_key_test.go
+++ b/integration-tests/code/getKSAKeyTest/getKSA_key_test.go
@@ -4,6 +4,8 @@ import (
 	"bytes"
 	"encoding/json"
 	"fmt"
+	"strings"
+
 	"io"
 	"net/http"
 	"os"
@@ -14,6 +16,12 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
+type Update struct {
+	Path  string
+	Value string
+	JSON  string
+}
+
 // For log file.
 type LogFile struct {
 	Source string            `json:"source"`
@@ -71,17 +79,6 @@ func TestGetKSAKey(t *testing.T) { //nolint:gocyclo
 		logFileURL2 = logFileURL_ENV2
 	}
 
-	output, err := integration_test_utils.GnmicCommand(kms2URL, "set", "--update-path", "key-routing-sessions/routing-sessions[path-id=38e0588b-6a2d-42c9-85a0-887cc877c299]", "--update-file", "../../config/kms/kms_2.json")
-	if err != nil {
-		t.Errorf("Error setting routing-session: %s; %s", err, output)
-	}
-	output, err = integration_test_utils.GnmicCommand(kms1URL, "set", "--update-path", "key-routing-sessions/routing-sessions[path-id=38e0588b-6a2d-42c9-85a0-887cc877c299]", "--update-file", "../../config/kms/kms_1.json")
-	if err != nil {
-		t.Errorf("Error setting routing-session: %s; %s", err, output)
-	}
-
-	time.Sleep(time.Duration(2) * time.Second)
-
 	url := fmt.Sprintf("http://%s/api/v1/keys/ksa_key_req", kms1AkmsURL)
 	data := RequestData{
 		ReceivingCKMSID: "5e41c291-6121-4335-84f6-41e04b8bdaa2",
@@ -111,6 +108,102 @@ func TestGetKSAKey(t *testing.T) { //nolint:gocyclo
 		t.Errorf("Expected status code 204 No Content, but got %d", resp.StatusCode)
 	}
 
+	time.Sleep(time.Duration(2) * time.Second)
+
+	output, err := integration_test_utils.GnmicCommand(kms1URL, "get", "--path", "create-route-requests")
+	if err != nil {
+		t.Errorf("Error getting create-route-requests: %s; %s", err, output)
+	}
+
+	output = strings.Split(output, "\"kms-path-id\": \"")[1]
+	output = strings.Split(output, "\",")[0]
+
+	path := fmt.Sprintf("key-routing-sessions/routing-sessions[path-id=%s]", output)
+
+	config01 := []Update{
+		{
+			Path: path,
+			JSON: fmt.Sprintf(`{"path-id": "%s"}`, output),
+		},
+		{
+			Path: fmt.Sprint(path, "/prev-hop"),
+			JSON: fmt.Sprintf(`{"node-id": "%s"}`, "5e41c291-6121-4335-84f6-41e04b8bdaa2"),
+		},
+		{
+			Path: fmt.Sprint(path, "/prev-hop"),
+			JSON: fmt.Sprintf(`{"hostname": "%s"}`, "kms_2"),
+		},
+		{
+			Path: fmt.Sprint(path, "/prev-hop"),
+			JSON: fmt.Sprintf(`{"port": %d}`, 50910),
+		},
+		{
+			Path: fmt.Sprint(path, "/initiating-kms-address"),
+			JSON: fmt.Sprintf(`{"node-id": "%s"}`, "5e41c291-6121-4335-84f6-41e04b8bdaa2"),
+		},
+		{
+			Path: fmt.Sprint(path, "/initiating-kms-address"),
+			JSON: fmt.Sprintf(`{"hostname": "%s"}`, "kms_2"),
+		},
+		{
+			Path: fmt.Sprint(path, "/initiating-kms-address"),
+			JSON: fmt.Sprintf(`{"port": %d}`, 50910),
+		},
+	}
+
+	config02 := []Update{
+		{
+			Path: path,
+			JSON: fmt.Sprintf(`{"path-id": "%s"}`, output),
+		},
+		{
+			Path: fmt.Sprint(path, "/next-hop"),
+			JSON: fmt.Sprintf(`{"node-id": "%s"}`, "0ff33c82-7fe1-482b-a0ca-67565806ee4b"),
+		},
+		{
+			Path: fmt.Sprint(path, "/next-hop"),
+			JSON: fmt.Sprintf(`{"hostname": "%s"}`, "kms_1"),
+		},
+		{
+			Path: fmt.Sprint(path, "/next-hop"),
+			JSON: fmt.Sprintf(`{"port": %d}`, 50910),
+		},
+		{
+			Path: fmt.Sprint(path, "/initiating-kms-address"),
+			JSON: fmt.Sprintf(`{"node-id": "%s"}`, "0ff33c82-7fe1-482b-a0ca-67565806ee4b"),
+		},
+		{
+			Path: fmt.Sprint(path, "/initiating-kms-address"),
+			JSON: fmt.Sprintf(`{"hostname": "%s"}`, "kms_1"),
+		},
+		{
+			Path: fmt.Sprint(path, "/initiating-kms-address"),
+			JSON: fmt.Sprintf(`{"port": %d}`, 50910),
+		},
+	}
+
+	argsKMS1 := []string{"set"}
+	for _, update := range config01 {
+		argsKMS1 = append(argsKMS1, "--update-path", update.Path, "--update-value", update.JSON)
+	}
+
+	argsKMS2 := []string{"set"}
+	for _, update := range config02 {
+		argsKMS2 = append(argsKMS2, "--update-path", update.Path, "--update-value", update.JSON)
+	}
+
+	output, err = integration_test_utils.GnmicCommand(kms1URL, argsKMS1...)
+	if err != nil {
+		t.Errorf("Error setting routing-session: %s; %s", err, output)
+	}
+
+	output, err = integration_test_utils.GnmicCommand(kms2URL, argsKMS2...)
+	if err != nil {
+		t.Errorf("Error setting routing-session: %s; %s", err, output)
+	}
+
+	time.Sleep(time.Duration(2) * time.Second)
+
 	// Get logfile of akms
 	resp, err = http.Get("http://" + logFileURL + "/debug/get_log_file")
 	if err != nil {