diff --git a/rw_core/core/device/logical_agent.go b/rw_core/core/device/logical_agent.go
index f032a65..15eb677 100644
--- a/rw_core/core/device/logical_agent.go
+++ b/rw_core/core/device/logical_agent.go
@@ -19,9 +19,7 @@
 import (
 	"context"
 	"encoding/hex"
-	"errors"
 	"fmt"
-	"strconv"
 	"sync"
 	"time"
 
@@ -67,27 +65,6 @@
 	groupLock sync.RWMutex
 }
 
-//MeterChunk keeps a meter entry and its lock. The lock in the struct is used to syncronize the
-//modifications for the related meter.
-type MeterChunk struct {
-	meter *ofp.OfpMeterEntry
-	lock  sync.Mutex
-}
-
-//FlowChunk keeps a flow and the lock for this flow. The lock in the struct is used to syncronize the
-//modifications for the related flow.
-type FlowChunk struct {
-	flow *ofp.OfpFlowStats
-	lock sync.Mutex
-}
-
-//GroupChunk keeps a group entry and its lock. The lock in the struct is used to syncronize the
-//modifications for the related group.
-type GroupChunk struct {
-	group *ofp.OfpGroupEntry
-	lock  sync.Mutex
-}
-
 func newLogicalDeviceAgent(id string, sn string, deviceID string, ldeviceMgr *LogicalManager,
 	deviceMgr *Manager, cdProxy *model.Proxy, timeout time.Duration) *LogicalAgent {
 	var agent LogicalAgent
@@ -238,333 +215,12 @@
 	return proto.Clone(agent.logicalDevice).(*voltha.LogicalDevice), nil
 }
 
-// ListLogicalDeviceFlows returns logical device flows
-func (agent *LogicalAgent) ListLogicalDeviceFlows(ctx context.Context) (*ofp.Flows, error) {
-	logger.Debug("ListLogicalDeviceFlows")
-	var flowStats []*ofp.OfpFlowStats
-	agent.flowLock.RLock()
-	defer agent.flowLock.RUnlock()
-	for _, flowChunk := range agent.flows {
-		flowStats = append(flowStats, (proto.Clone(flowChunk.flow)).(*ofp.OfpFlowStats))
-	}
-	return &ofp.Flows{Items: flowStats}, nil
-}
-
-// ListLogicalDeviceMeters returns logical device meters
-func (agent *LogicalAgent) ListLogicalDeviceMeters(ctx context.Context) (*ofp.Meters, error) {
-	logger.Debug("ListLogicalDeviceMeters")
-
-	var meterEntries []*ofp.OfpMeterEntry
-	agent.meterLock.RLock()
-	defer agent.meterLock.RUnlock()
-	for _, meterChunk := range agent.meters {
-		meterEntries = append(meterEntries, (proto.Clone(meterChunk.meter)).(*ofp.OfpMeterEntry))
-	}
-	return &ofp.Meters{Items: meterEntries}, nil
-}
-
-// ListLogicalDeviceFlowGroups returns logical device flow groups
-func (agent *LogicalAgent) ListLogicalDeviceFlowGroups(ctx context.Context) (*ofp.FlowGroups, error) {
-	logger.Debug("ListLogicalDeviceFlowGroups")
-
-	var groupEntries []*ofp.OfpGroupEntry
-	agent.groupLock.RLock()
-	defer agent.groupLock.RUnlock()
-	for _, value := range agent.groups {
-		groupEntries = append(groupEntries, (proto.Clone(value.group)).(*ofp.OfpGroupEntry))
-	}
-	return &ofp.FlowGroups{Items: groupEntries}, nil
-}
-
-// ListLogicalDevicePorts returns logical device ports
-func (agent *LogicalAgent) ListLogicalDevicePorts(ctx context.Context) (*voltha.LogicalPorts, error) {
-	logger.Debug("ListLogicalDevicePorts")
-	logicalDevice, err := agent.GetLogicalDevice(ctx)
-	if err != nil {
-		return nil, err
-	}
-	if logicalDevice == nil {
-		return &voltha.LogicalPorts{}, nil
-	}
-	lPorts := make([]*voltha.LogicalPort, 0)
-	lPorts = append(lPorts, logicalDevice.Ports...)
-	return &voltha.LogicalPorts{Items: lPorts}, nil
-}
-
-//updateLogicalDeviceFlow updates flow in the store and cache
-//It is assumed that the chunk lock has been acquired before this function is called
-func (agent *LogicalAgent) updateLogicalDeviceFlow(ctx context.Context, flow *ofp.OfpFlowStats, flowChunk *FlowChunk) error {
-	path := fmt.Sprintf("logical_flows/%s/%d", agent.logicalDeviceID, flow.Id)
-	if err := agent.clusterDataProxy.Update(ctx, path, flow); err != nil {
-		return status.Errorf(codes.Internal, "failed-update-flow:%s:%d %s", agent.logicalDeviceID, flow.Id, err)
-	}
-	flowChunk.flow = flow
-	return nil
-}
-
-//removeLogicalDeviceFlow deletes the flow from store and cache.
-//It is assumed that the chunk lock has been acquired before this function is called
-func (agent *LogicalAgent) removeLogicalDeviceFlow(ctx context.Context, flowID uint64) error {
-	path := fmt.Sprintf("logical_flows/%s/%d", agent.logicalDeviceID, flowID)
-	if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
-		return fmt.Errorf("couldnt-delete-flow-from-the-store-%s", path)
-	}
-	agent.flowLock.Lock()
-	defer agent.flowLock.Unlock()
-	delete(agent.flows, flowID)
-	return nil
-}
-
-//updateLogicalDeviceMeter updates meter info in store and cache
-//It is assumed that the chunk lock has been acquired before this function is called
-func (agent *LogicalAgent) updateLogicalDeviceMeter(ctx context.Context, meter *ofp.OfpMeterEntry, meterChunk *MeterChunk) error {
-	path := fmt.Sprintf("meters/%s/%d", agent.logicalDeviceID, meter.Config.MeterId)
-	if err := agent.clusterDataProxy.Update(ctx, path, meter); err != nil {
-		logger.Errorw("error-updating-logical-device-with-meters", log.Fields{"error": err})
-		return err
-	}
-	meterChunk.meter = meter
-	return nil
-}
-
-//removeLogicalDeviceMeter deletes the meter from store and cache
-//It is assumed that the chunk lock has been acquired before this function is called
-func (agent *LogicalAgent) removeLogicalDeviceMeter(ctx context.Context, meterID uint32) error {
-	path := fmt.Sprintf("meters/%s/%d", agent.logicalDeviceID, meterID)
-	if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
-		return fmt.Errorf("couldnt-delete-meter-from-store-%s", path)
-	}
-	agent.meterLock.Lock()
-	defer agent.meterLock.Unlock()
-	delete(agent.meters, meterID)
-	return nil
-}
-
-//updateLogicalDeviceFlowGroup updates the flow groups in store and cache
-//It is assumed that the chunk lock has been acquired before this function is called
-func (agent *LogicalAgent) updateLogicalDeviceFlowGroup(ctx context.Context, groupEntry *ofp.OfpGroupEntry, groupChunk *GroupChunk) error {
-	path := fmt.Sprintf("groups/%s/%d", agent.logicalDeviceID, groupEntry.Desc.GroupId)
-	if err := agent.clusterDataProxy.Update(ctx, path, groupEntry); err != nil {
-		logger.Errorw("error-updating-logical-device-with-group", log.Fields{"error": err})
-		return err
-	}
-	groupChunk.group = groupEntry
-	return nil
-}
-
-//removeLogicalDeviceFlowGroup removes the flow groups in store and cache
-//It is assumed that the chunk lock has been acquired before this function is called
-func (agent *LogicalAgent) removeLogicalDeviceFlowGroup(ctx context.Context, groupID uint32) error {
-	path := fmt.Sprintf("groups/%s/%d", agent.logicalDeviceID, groupID)
-	if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
-		return fmt.Errorf("couldnt-delete-group-from-store-%s", path)
-	}
-	agent.groupLock.Lock()
-	defer agent.groupLock.Unlock()
-	delete(agent.groups, groupID)
-	return nil
-}
-
 // getLogicalDeviceWithoutLock returns a cloned logical device to a function that already holds the agent lock.
 func (agent *LogicalAgent) getLogicalDeviceWithoutLock() *voltha.LogicalDevice {
 	logger.Debug("getLogicalDeviceWithoutLock")
 	return proto.Clone(agent.logicalDevice).(*voltha.LogicalDevice)
 }
 
-func (agent *LogicalAgent) updateLogicalPort(ctx context.Context, device *voltha.Device, port *voltha.Port) error {
-	logger.Debugw("updateLogicalPort", log.Fields{"deviceId": device.Id, "port": port})
-	var err error
-	if port.Type == voltha.Port_ETHERNET_NNI {
-		if _, err = agent.addNNILogicalPort(ctx, device, port); err != nil {
-			return err
-		}
-		agent.addLogicalPortToMap(port.PortNo, true)
-	} else if port.Type == voltha.Port_ETHERNET_UNI {
-		if _, err = agent.addUNILogicalPort(ctx, device, port); err != nil {
-			return err
-		}
-		agent.addLogicalPortToMap(port.PortNo, false)
-	} else {
-		// Update the device routes to ensure all routes on the logical device have been calculated
-		if err = agent.buildRoutes(ctx); err != nil {
-			// Not an error - temporary state
-			logger.Warnw("failed-to-update-routes", log.Fields{"device-id": device.Id, "port": port, "error": err})
-		}
-	}
-	return nil
-}
-
-// setupLogicalPorts is invoked once the logical device has been created and is ready to get ports
-// added to it.  While the logical device was being created we could have received requests to add
-// NNI and UNI ports which were discarded.  Now is the time to add them if needed
-func (agent *LogicalAgent) setupLogicalPorts(ctx context.Context) error {
-	logger.Infow("setupLogicalPorts", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
-	// First add any NNI ports which could have been missing
-	if err := agent.setupNNILogicalPorts(ctx, agent.rootDeviceID); err != nil {
-		logger.Errorw("error-setting-up-NNI-ports", log.Fields{"error": err, "deviceId": agent.rootDeviceID})
-		return err
-	}
-
-	// Now, set up the UNI ports if needed.
-	children, err := agent.deviceMgr.GetAllChildDevices(ctx, agent.rootDeviceID)
-	if err != nil {
-		logger.Errorw("error-getting-child-devices", log.Fields{"error": err, "deviceId": agent.rootDeviceID})
-		return err
-	}
-	responses := make([]coreutils.Response, 0)
-	for _, child := range children.Items {
-		response := coreutils.NewResponse()
-		responses = append(responses, response)
-		go func(child *voltha.Device) {
-			if err = agent.setupUNILogicalPorts(context.Background(), child); err != nil {
-				logger.Error("setting-up-UNI-ports-failed", log.Fields{"deviceID": child.Id})
-				response.Error(status.Errorf(codes.Internal, "UNI-ports-setup-failed: %s", child.Id))
-			}
-			response.Done()
-		}(child)
-	}
-	// Wait for completion
-	if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, responses...); res != nil {
-		return status.Errorf(codes.Aborted, "errors-%s", res)
-	}
-	return nil
-}
-
-// setupNNILogicalPorts creates an NNI port on the logical device that represents an NNI interface on a root device
-func (agent *LogicalAgent) setupNNILogicalPorts(ctx context.Context, deviceID string) error {
-	logger.Infow("setupNNILogicalPorts-start", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
-	// Build the logical device based on information retrieved from the device adapter
-	var err error
-
-	var device *voltha.Device
-	if device, err = agent.deviceMgr.getDevice(ctx, deviceID); err != nil {
-		logger.Errorw("error-retrieving-device", log.Fields{"error": err, "deviceId": deviceID})
-		return err
-	}
-
-	//Get UNI port number
-	for _, port := range device.Ports {
-		if port.Type == voltha.Port_ETHERNET_NNI {
-			if _, err = agent.addNNILogicalPort(ctx, device, port); err != nil {
-				logger.Errorw("error-adding-UNI-port", log.Fields{"error": err})
-			}
-			agent.addLogicalPortToMap(port.PortNo, true)
-		}
-	}
-	return err
-}
-
-// updatePortState updates the port state of the device
-func (agent *LogicalAgent) updatePortState(ctx context.Context, deviceID string, portNo uint32, operStatus voltha.OperStatus_Types) error {
-	logger.Infow("updatePortState-start", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "portNo": portNo, "state": operStatus})
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return err
-	}
-	defer agent.requestQueue.RequestComplete()
-	// Get the latest logical device info
-	original := agent.getLogicalDeviceWithoutLock()
-	updatedPorts := clonePorts(original.Ports)
-	for _, port := range updatedPorts {
-		if port.DeviceId == deviceID && port.DevicePortNo == portNo {
-			if operStatus == voltha.OperStatus_ACTIVE {
-				port.OfpPort.Config = port.OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
-			} else {
-				port.OfpPort.Config = port.OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
-			}
-			// Update the logical device
-			if err := agent.updateLogicalDevicePortsWithoutLock(ctx, original, updatedPorts); err != nil {
-				logger.Errorw("error-updating-logical-device", log.Fields{"error": err})
-				return err
-			}
-			return nil
-		}
-	}
-	return status.Errorf(codes.NotFound, "port-%d-not-exist", portNo)
-}
-
-// updatePortsState updates the ports state related to the device
-func (agent *LogicalAgent) updatePortsState(ctx context.Context, device *voltha.Device, state voltha.OperStatus_Types) error {
-	logger.Infow("updatePortsState-start", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return err
-	}
-	defer agent.requestQueue.RequestComplete()
-	// Get the latest logical device info
-	original := agent.getLogicalDeviceWithoutLock()
-	updatedPorts := clonePorts(original.Ports)
-	for _, port := range updatedPorts {
-		if port.DeviceId == device.Id {
-			if state == voltha.OperStatus_ACTIVE {
-				port.OfpPort.Config = port.OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
-			} else {
-				port.OfpPort.Config = port.OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
-			}
-		}
-	}
-	// Updating the logical device will trigger the poprt change events to be populated to the controller
-	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, original, updatedPorts); err != nil {
-		logger.Warnw("logical-device-update-failed", log.Fields{"ldeviceId": agent.logicalDeviceID, "error": err})
-		return err
-	}
-	return nil
-}
-
-// setupUNILogicalPorts creates a UNI port on the logical device that represents a child UNI interface
-func (agent *LogicalAgent) setupUNILogicalPorts(ctx context.Context, childDevice *voltha.Device) error {
-	logger.Infow("setupUNILogicalPort", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
-	// Build the logical device based on information retrieved from the device adapter
-	var err error
-	var added bool
-	//Get UNI port number
-	for _, port := range childDevice.Ports {
-		if port.Type == voltha.Port_ETHERNET_UNI {
-			if added, err = agent.addUNILogicalPort(ctx, childDevice, port); err != nil {
-				logger.Errorw("error-adding-UNI-port", log.Fields{"error": err})
-			}
-			if added {
-				agent.addLogicalPortToMap(port.PortNo, false)
-			}
-		}
-	}
-	return err
-}
-
-// deleteAllLogicalPorts deletes all logical ports associated with this logical device
-func (agent *LogicalAgent) deleteAllLogicalPorts(ctx context.Context) error {
-	logger.Infow("updatePortsState-start", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return err
-	}
-	defer agent.requestQueue.RequestComplete()
-	// Get the latest logical device info
-	cloned := agent.getLogicalDeviceWithoutLock()
-
-	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, cloned, []*voltha.LogicalPort{}); err != nil {
-		logger.Warnw("logical-device-update-failed", log.Fields{"ldeviceId": agent.logicalDeviceID, "error": err})
-		return err
-	}
-	return nil
-}
-
-func clonePorts(ports []*voltha.LogicalPort) []*voltha.LogicalPort {
-	return proto.Clone(&voltha.LogicalPorts{Items: ports}).(*voltha.LogicalPorts).Items
-}
-
-//updateLogicalDevicePortsWithoutLock updates the
-func (agent *LogicalAgent) updateLogicalDevicePortsWithoutLock(ctx context.Context, device *voltha.LogicalDevice, newPorts []*voltha.LogicalPort) error {
-	oldPorts := device.Ports
-	device.Ports = newPorts
-	if err := agent.updateLogicalDeviceWithoutLock(ctx, device); err != nil {
-		return err
-	}
-	agent.portUpdated(oldPorts, newPorts)
-	return nil
-}
-
 //updateLogicalDeviceWithoutLock updates the model with the logical device.  It clones the logicaldevice before saving it
 func (agent *LogicalAgent) updateLogicalDeviceWithoutLock(ctx context.Context, logicalDevice *voltha.LogicalDevice) error {
 	if agent.stopped {
@@ -582,547 +238,6 @@
 	return nil
 }
 
-//generateDeviceRoutesIfNeeded generates the device routes if the logical device has been updated since the last time
-//that device graph was generated.
-func (agent *LogicalAgent) generateDeviceRoutesIfNeeded(ctx context.Context) error {
-	agent.lockDeviceRoutes.Lock()
-	defer agent.lockDeviceRoutes.Unlock()
-
-	ld, err := agent.GetLogicalDevice(ctx)
-	if err != nil {
-		return err
-	}
-
-	if agent.deviceRoutes != nil && agent.deviceRoutes.IsUpToDate(ld) {
-		return nil
-	}
-	logger.Debug("Generation of device route required")
-	if err := agent.buildRoutes(ctx); err != nil {
-		// No Route is not an error
-		if !errors.Is(err, route.ErrNoRoute) {
-			return err
-		}
-	}
-	return nil
-}
-
-//updateFlowTable updates the flow table of that logical device
-func (agent *LogicalAgent) updateFlowTable(ctx context.Context, flow *ofp.OfpFlowMod) error {
-	logger.Debug("UpdateFlowTable")
-	if flow == nil {
-		return nil
-	}
-
-	if err := agent.generateDeviceRoutesIfNeeded(ctx); err != nil {
-		return err
-	}
-	switch flow.GetCommand() {
-	case ofp.OfpFlowModCommand_OFPFC_ADD:
-		return agent.flowAdd(ctx, flow)
-	case ofp.OfpFlowModCommand_OFPFC_DELETE:
-		return agent.flowDelete(ctx, flow)
-	case ofp.OfpFlowModCommand_OFPFC_DELETE_STRICT:
-		return agent.flowDeleteStrict(ctx, flow)
-	case ofp.OfpFlowModCommand_OFPFC_MODIFY:
-		return agent.flowModify(flow)
-	case ofp.OfpFlowModCommand_OFPFC_MODIFY_STRICT:
-		return agent.flowModifyStrict(flow)
-	}
-	return status.Errorf(codes.Internal,
-		"unhandled-command: lDeviceId:%s, command:%s", agent.logicalDeviceID, flow.GetCommand())
-}
-
-//updateGroupTable updates the group table of that logical device
-func (agent *LogicalAgent) updateGroupTable(ctx context.Context, groupMod *ofp.OfpGroupMod) error {
-	logger.Debug("updateGroupTable")
-	if groupMod == nil {
-		return nil
-	}
-
-	if err := agent.generateDeviceRoutesIfNeeded(ctx); err != nil {
-		return err
-	}
-
-	switch groupMod.GetCommand() {
-	case ofp.OfpGroupModCommand_OFPGC_ADD:
-		return agent.groupAdd(ctx, groupMod)
-	case ofp.OfpGroupModCommand_OFPGC_DELETE:
-		return agent.groupDelete(ctx, groupMod)
-	case ofp.OfpGroupModCommand_OFPGC_MODIFY:
-		return agent.groupModify(ctx, groupMod)
-	}
-	return status.Errorf(codes.Internal,
-		"unhandled-command: lDeviceId:%s, command:%s", agent.logicalDeviceID, groupMod.GetCommand())
-}
-
-// updateMeterTable updates the meter table of that logical device
-func (agent *LogicalAgent) updateMeterTable(ctx context.Context, meterMod *ofp.OfpMeterMod) error {
-	logger.Debug("updateMeterTable")
-	if meterMod == nil {
-		return nil
-	}
-	switch meterMod.GetCommand() {
-	case ofp.OfpMeterModCommand_OFPMC_ADD:
-		return agent.meterAdd(ctx, meterMod)
-	case ofp.OfpMeterModCommand_OFPMC_DELETE:
-		return agent.meterDelete(ctx, meterMod)
-	case ofp.OfpMeterModCommand_OFPMC_MODIFY:
-		return agent.meterModify(ctx, meterMod)
-	}
-	return status.Errorf(codes.Internal,
-		"unhandled-command: lDeviceId:%s, command:%s", agent.logicalDeviceID, meterMod.GetCommand())
-
-}
-
-func (agent *LogicalAgent) meterAdd(ctx context.Context, meterMod *ofp.OfpMeterMod) error {
-	logger.Debugw("meterAdd", log.Fields{"metermod": *meterMod})
-	if meterMod == nil {
-		return nil
-	}
-
-	meterEntry := fu.MeterEntryFromMeterMod(meterMod)
-	agent.meterLock.Lock()
-	//check if the meter already exists or not
-	_, ok := agent.meters[meterMod.MeterId]
-	if ok {
-		logger.Infow("Meter-already-exists", log.Fields{"meter": *meterMod})
-		agent.meterLock.Unlock()
-		return nil
-	}
-
-	mChunk := MeterChunk{
-		meter: meterEntry,
-	}
-	//Add to map and acquire the per meter lock
-	agent.meters[meterMod.MeterId] = &mChunk
-	mChunk.lock.Lock()
-	defer mChunk.lock.Unlock()
-	agent.meterLock.Unlock()
-	meterID := strconv.Itoa(int(meterMod.MeterId))
-	if err := agent.clusterDataProxy.AddWithID(ctx, "meters/"+agent.logicalDeviceID, meterID, meterEntry); err != nil {
-		logger.Errorw("failed-adding-meter", log.Fields{"deviceID": agent.logicalDeviceID, "meterID": meterID, "err": err})
-		//Revert the map
-		agent.meterLock.Lock()
-		delete(agent.meters, meterMod.MeterId)
-		agent.meterLock.Unlock()
-		return err
-	}
-
-	logger.Debugw("Meter-added-successfully", log.Fields{"Added-meter": meterEntry})
-	return nil
-}
-
-func (agent *LogicalAgent) meterDelete(ctx context.Context, meterMod *ofp.OfpMeterMod) error {
-	logger.Debug("meterDelete", log.Fields{"meterMod": *meterMod})
-	if meterMod == nil {
-		return nil
-	}
-	agent.meterLock.RLock()
-	meterChunk, ok := agent.meters[meterMod.MeterId]
-	agent.meterLock.RUnlock()
-	if ok {
-		//Dont let anyone to do any changes to this meter until this is done.
-		//And wait if someone else is already making modifications. Do this with per meter lock.
-		meterChunk.lock.Lock()
-		defer meterChunk.lock.Unlock()
-		if err := agent.deleteFlowsOfMeter(ctx, meterMod.MeterId); err != nil {
-			return err
-		}
-		//remove from the store and cache
-		if err := agent.removeLogicalDeviceMeter(ctx, meterMod.MeterId); err != nil {
-			return err
-		}
-		logger.Debugw("meterDelete-success", log.Fields{"meterID": meterMod.MeterId})
-	} else {
-		logger.Warnw("meter-not-found", log.Fields{"meterID": meterMod.MeterId})
-	}
-	return nil
-}
-
-func (agent *LogicalAgent) meterModify(ctx context.Context, meterMod *ofp.OfpMeterMod) error {
-	logger.Debug("meterModify")
-	if meterMod == nil {
-		return nil
-	}
-	newMeter := fu.MeterEntryFromMeterMod(meterMod)
-	agent.meterLock.RLock()
-	meterChunk, ok := agent.meters[newMeter.Config.MeterId]
-	agent.meterLock.RUnlock()
-	if !ok {
-		return fmt.Errorf("no-meter-to-modify:%d", newMeter.Config.MeterId)
-	}
-	//Release the map lock and syncronize per meter
-	meterChunk.lock.Lock()
-	defer meterChunk.lock.Unlock()
-	oldMeter := meterChunk.meter
-	newMeter.Stats.FlowCount = oldMeter.Stats.FlowCount
-
-	if err := agent.updateLogicalDeviceMeter(ctx, newMeter, meterChunk); err != nil {
-		logger.Errorw("db-meter-update-failed", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "meterID": newMeter.Config.MeterId})
-		return err
-	}
-	logger.Debugw("replaced-with-new-meter", log.Fields{"oldMeter": oldMeter, "newMeter": newMeter})
-	return nil
-
-}
-
-func (agent *LogicalAgent) deleteFlowsOfMeter(ctx context.Context, meterID uint32) error {
-	logger.Infow("Delete-flows-matching-meter", log.Fields{"meter": meterID})
-	agent.flowLock.Lock()
-	defer agent.flowLock.Unlock()
-	for flowID, flowChunk := range agent.flows {
-		if mID := fu.GetMeterIdFromFlow(flowChunk.flow); mID != 0 && mID == meterID {
-			logger.Debugw("Flow-to-be- deleted", log.Fields{"flow": flowChunk.flow})
-			path := fmt.Sprintf("logical_flows/%s/%d", agent.logicalDeviceID, flowID)
-			if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
-				//TODO: Think on carrying on and deleting the remaining flows, instead of returning.
-				//Anyways this returns an error to controller which possibly results with a re-deletion.
-				//Then how can we handle the new deletion request(Same for group deletion)?
-				return fmt.Errorf("couldnt-deleted-flow-from-store-%s", path)
-			}
-			delete(agent.flows, flowID)
-		}
-	}
-	return nil
-}
-
-func (agent *LogicalAgent) updateFlowCountOfMeterStats(ctx context.Context, modCommand *ofp.OfpFlowMod, flow *ofp.OfpFlowStats, revertUpdate bool) bool {
-
-	flowCommand := modCommand.GetCommand()
-	meterID := fu.GetMeterIdFromFlow(flow)
-	logger.Debugw("Meter-id-in-flow-mod", log.Fields{"meterId": meterID})
-	if meterID == 0 {
-		logger.Debugw("No-meter-present-in-the-flow", log.Fields{"flow": *flow})
-		return true
-	}
-
-	if flowCommand != ofp.OfpFlowModCommand_OFPFC_ADD && flowCommand != ofp.OfpFlowModCommand_OFPFC_DELETE_STRICT {
-		return true
-	}
-	agent.meterLock.RLock()
-	meterChunk, ok := agent.meters[meterID]
-	agent.meterLock.RUnlock()
-	if !ok {
-		logger.Debugw("Meter-is-not-present-in-logical-device", log.Fields{"meterID": meterID})
-		return true
-	}
-
-	//acquire the meter lock
-	meterChunk.lock.Lock()
-	defer meterChunk.lock.Unlock()
-
-	if flowCommand == ofp.OfpFlowModCommand_OFPFC_ADD {
-		if revertUpdate {
-			meterChunk.meter.Stats.FlowCount--
-		} else {
-			meterChunk.meter.Stats.FlowCount++
-		}
-	} else if flowCommand == ofp.OfpFlowModCommand_OFPFC_DELETE_STRICT {
-		if revertUpdate {
-			meterChunk.meter.Stats.FlowCount++
-		} else {
-			meterChunk.meter.Stats.FlowCount--
-		}
-	}
-
-	//	Update store and cache
-	if err := agent.updateLogicalDeviceMeter(ctx, meterChunk.meter, meterChunk); err != nil {
-		logger.Debugw("unable-to-update-meter-in-db", log.Fields{"logicalDevice": agent.logicalDeviceID, "meterID": meterID})
-		return false
-	}
-
-	logger.Debugw("updated-meter-flow-stats", log.Fields{"meterId": meterID})
-	return true
-}
-
-//flowAdd adds a flow to the flow table of that logical device
-func (agent *LogicalAgent) flowAdd(ctx context.Context, mod *ofp.OfpFlowMod) error {
-	logger.Debugw("flowAdd", log.Fields{"flow": mod})
-	if mod == nil {
-		return nil
-	}
-	flow, err := fu.FlowStatsEntryFromFlowModMessage(mod)
-	if err != nil {
-		logger.Errorw("flowAdd-failed", log.Fields{"flowMod": mod, "err": err})
-		return err
-	}
-	var updated bool
-	var changed bool
-	if changed, updated, err = agent.decomposeAndAdd(ctx, flow, mod); err != nil {
-		logger.Errorw("flow-decompose-and-add-failed ", log.Fields{"flowMod": mod, "err": err})
-		return err
-	}
-	if changed && !updated {
-		if dbupdated := agent.updateFlowCountOfMeterStats(ctx, mod, flow, false); !dbupdated {
-			return fmt.Errorf("couldnt-updated-flow-stats-%s", strconv.FormatUint(flow.Id, 10))
-		}
-	}
-	return nil
-
-}
-
-func (agent *LogicalAgent) decomposeAndAdd(ctx context.Context, flow *ofp.OfpFlowStats, mod *ofp.OfpFlowMod) (bool, bool, error) {
-	changed := false
-	updated := false
-	alreadyExist := true
-	var flowToReplace *ofp.OfpFlowStats
-
-	//if flow is not found in the map, create a new entry, otherwise get the existing one.
-	agent.flowLock.Lock()
-	flowChunk, ok := agent.flows[flow.Id]
-	if !ok {
-		flowChunk = &FlowChunk{
-			flow: flow,
-		}
-		agent.flows[flow.Id] = flowChunk
-		alreadyExist = false
-		flowChunk.lock.Lock() //acquire chunk lock before releasing map lock
-		defer flowChunk.lock.Unlock()
-		agent.flowLock.Unlock()
-	} else {
-		agent.flowLock.Unlock() //release map lock before acquiring chunk lock
-		flowChunk.lock.Lock()
-		defer flowChunk.lock.Unlock()
-	}
-
-	if !alreadyExist {
-		flowID := strconv.FormatUint(flow.Id, 10)
-		if err := agent.clusterDataProxy.AddWithID(ctx, "logical_flows/"+agent.logicalDeviceID, flowID, flow); err != nil {
-			logger.Errorw("failed-adding-flow-to-db", log.Fields{"deviceID": agent.logicalDeviceID, "flowID": flowID, "err": err})
-			//Revert the map
-			//TODO: Solve the condition:If we have two flow Adds of the same flow (at least same priority and match) in quick succession
-			//then if the first one fails while the second one was waiting on the flowchunk, we will end up with an instance of flowChunk that is no longer in the map.
-			agent.flowLock.Lock()
-			delete(agent.flows, flow.Id)
-			agent.flowLock.Unlock()
-			return changed, updated, err
-		}
-	}
-	flows := make([]*ofp.OfpFlowStats, 0)
-	updatedFlows := make([]*ofp.OfpFlowStats, 0)
-	checkOverlap := (mod.Flags & uint32(ofp.OfpFlowModFlags_OFPFF_CHECK_OVERLAP)) != 0
-	if checkOverlap {
-		if overlapped := fu.FindOverlappingFlows(flows, mod); len(overlapped) != 0 {
-			//	TODO:  should this error be notified other than being logged?
-			logger.Warnw("overlapped-flows", log.Fields{"logicaldeviceId": agent.logicalDeviceID})
-		} else {
-			//	Add flow
-			changed = true
-		}
-	} else {
-		if alreadyExist {
-			flowToReplace = flowChunk.flow
-			if (mod.Flags & uint32(ofp.OfpFlowModFlags_OFPFF_RESET_COUNTS)) != 0 {
-				flow.ByteCount = flowToReplace.ByteCount
-				flow.PacketCount = flowToReplace.PacketCount
-			}
-			if !proto.Equal(flowToReplace, flow) {
-				changed = true
-				updated = true
-			}
-		} else {
-			changed = true
-		}
-	}
-	logger.Debugw("flowAdd-changed", log.Fields{"changed": changed, "updated": updated})
-	if changed {
-		updatedFlows = append(updatedFlows, flow)
-		var flowMetadata voltha.FlowMetadata
-		lMeters, _ := agent.ListLogicalDeviceMeters(ctx)
-		if err := agent.GetMeterConfig(updatedFlows, lMeters.Items, &flowMetadata); err != nil {
-			logger.Error("Meter-referred-in-flow-not-present")
-			return changed, updated, err
-		}
-		flowGroups, _ := agent.ListLogicalDeviceFlowGroups(ctx)
-		deviceRules, err := agent.flowDecomposer.DecomposeRules(ctx, agent, ofp.Flows{Items: updatedFlows}, *flowGroups)
-		if err != nil {
-			return changed, updated, err
-		}
-
-		logger.Debugw("rules", log.Fields{"rules": deviceRules.String()})
-		//	Update store and cache
-		if updated {
-			if err := agent.updateLogicalDeviceFlow(ctx, flow, flowChunk); err != nil {
-				return changed, updated, err
-			}
-		}
-		respChannels := agent.addFlowsAndGroupsToDevices(ctx, deviceRules, &flowMetadata)
-		// Create the go routines to wait
-		go func() {
-			// Wait for completion
-			if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChannels...); res != nil {
-				logger.Infow("failed-to-add-flows-will-attempt-deletion", log.Fields{"errors": res, "logical-device-id": agent.logicalDeviceID})
-				// Revert added flows
-				if err := agent.revertAddedFlows(context.Background(), mod, flow, flowToReplace, deviceRules, &flowMetadata); err != nil {
-					logger.Errorw("failure-to-delete-flows-after-failed-addition", log.Fields{"logical-device-id": agent.logicalDeviceID, "error": err})
-				}
-			}
-		}()
-	}
-	return changed, updated, nil
-}
-
-// revertAddedFlows reverts flows after the flowAdd request has failed.  All flows corresponding to that flowAdd request
-// will be reverted, both from the logical devices and the devices.
-func (agent *LogicalAgent) revertAddedFlows(ctx context.Context, mod *ofp.OfpFlowMod, addedFlow *ofp.OfpFlowStats, replacedFlow *ofp.OfpFlowStats, deviceRules *fu.DeviceRules, metadata *voltha.FlowMetadata) error {
-	logger.Debugw("revertFlowAdd", log.Fields{"added-flow": addedFlow, "replaced-flow": replacedFlow, "device-rules": deviceRules, "metadata": metadata})
-
-	agent.flowLock.RLock()
-	flowChunk, ok := agent.flows[addedFlow.Id]
-	agent.flowLock.RUnlock()
-	if !ok {
-		// Not found - do nothing
-		log.Debugw("flow-not-found", log.Fields{"added-flow": addedFlow})
-		return nil
-	}
-	//Leave the map lock and syncronize per flow
-	flowChunk.lock.Lock()
-	defer flowChunk.lock.Unlock()
-
-	if replacedFlow != nil {
-		if err := agent.updateLogicalDeviceFlow(ctx, replacedFlow, flowChunk); err != nil {
-			return err
-		}
-	} else {
-		if err := agent.removeLogicalDeviceFlow(ctx, addedFlow.Id); err != nil {
-			return err
-		}
-	}
-	// Revert meters
-	if changedMeterStats := agent.updateFlowCountOfMeterStats(ctx, mod, addedFlow, true); !changedMeterStats {
-		return fmt.Errorf("Unable-to-revert-meterstats-for-flow-%s", strconv.FormatUint(addedFlow.Id, 10))
-	}
-
-	// Update the devices
-	respChnls := agent.deleteFlowsAndGroupsFromDevices(ctx, deviceRules, metadata)
-
-	// Wait for the responses
-	go func() {
-		// Since this action is taken following an add failure, we may also receive a failure for the revert
-		if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
-			logger.Warnw("failure-reverting-added-flows", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
-		}
-	}()
-
-	return nil
-}
-
-// GetMeterConfig returns meter config
-func (agent *LogicalAgent) GetMeterConfig(flows []*ofp.OfpFlowStats, meters []*ofp.OfpMeterEntry, metadata *voltha.FlowMetadata) error {
-	m := make(map[uint32]bool)
-	for _, flow := range flows {
-		if flowMeterID := fu.GetMeterIdFromFlow(flow); flowMeterID != 0 && !m[flowMeterID] {
-			foundMeter := false
-			// Meter is present in the flow , Get from logical device
-			for _, meter := range meters {
-				if flowMeterID == meter.Config.MeterId {
-					metadata.Meters = append(metadata.Meters, meter.Config)
-					logger.Debugw("Found meter in logical device",
-						log.Fields{"meterID": flowMeterID, "meter-band": meter.Config})
-					m[flowMeterID] = true
-					foundMeter = true
-					break
-				}
-			}
-			if !foundMeter {
-				logger.Errorw("Meter-referred-by-flow-is-not-found-in-logicaldevice",
-					log.Fields{"meterID": flowMeterID, "Available-meters": meters, "flow": *flow})
-				return fmt.Errorf("Meter-referred-by-flow-is-not-found-in-logicaldevice.MeterId-%d", flowMeterID)
-			}
-		}
-	}
-	logger.Debugw("meter-bands-for-flows", log.Fields{"flows": len(flows), "metadata": metadata})
-	return nil
-
-}
-
-//flowDelete deletes a flow from the flow table of that logical device
-func (agent *LogicalAgent) flowDelete(ctx context.Context, mod *ofp.OfpFlowMod) error {
-	logger.Debug("flowDelete")
-	if mod == nil {
-		return nil
-	}
-
-	fs, err := fu.FlowStatsEntryFromFlowModMessage(mod)
-	if err != nil {
-		return err
-	}
-
-	//build a list of what to delete
-	toDelete := make([]*ofp.OfpFlowStats, 0)
-	toDeleteChunks := make([]*FlowChunk, 0)
-	//Lock the map to search the matched flows
-	agent.flowLock.RLock()
-	for _, f := range agent.flows {
-		if fu.FlowMatch(f.flow, fs) {
-			toDelete = append(toDelete, f.flow)
-			toDeleteChunks = append(toDeleteChunks, f)
-			continue
-		}
-		// Check wild card match
-		if fu.FlowMatchesMod(f.flow, mod) {
-			toDelete = append(toDelete, f.flow)
-			toDeleteChunks = append(toDeleteChunks, f)
-		}
-	}
-	agent.flowLock.RUnlock()
-	//Delete the matched flows
-	if len(toDelete) > 0 {
-		logger.Debugw("flowDelete", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "toDelete": len(toDelete)})
-		var meters []*ofp.OfpMeterEntry
-		var flowGroups []*ofp.OfpGroupEntry
-		if ofpMeters, err := agent.ListLogicalDeviceMeters(ctx); err != nil {
-			meters = ofpMeters.Items
-		}
-
-		if groups, err := agent.ListLogicalDeviceFlowGroups(ctx); err != nil {
-			flowGroups = groups.Items
-		}
-
-		for _, fc := range toDeleteChunks {
-			if err := agent.deleteFlowAndUpdateMeterStats(ctx, mod, fc); err != nil {
-				return err
-			}
-		}
-		var flowMetadata voltha.FlowMetadata
-		if err := agent.GetMeterConfig(toDelete, meters, &flowMetadata); err != nil { // This should never happen
-			logger.Error("Meter-referred-in-flows-not-present")
-			return err
-		}
-		var respChnls []coreutils.Response
-		var partialRoute bool
-		var deviceRules *fu.DeviceRules
-		deviceRules, err = agent.flowDecomposer.DecomposeRules(ctx, agent, ofp.Flows{Items: toDelete}, ofp.FlowGroups{Items: flowGroups})
-		if err != nil {
-			// A no route error means no route exists between the ports specified in the flow. This can happen when the
-			// child device is deleted and a request to delete flows from the parent device is received
-			if !errors.Is(err, route.ErrNoRoute) {
-				logger.Errorw("unexpected-error-received", log.Fields{"flows-to-delete": toDelete, "error": err})
-				return err
-			}
-			partialRoute = true
-		}
-
-		// Update the devices
-		if partialRoute {
-			respChnls = agent.deleteFlowsFromParentDevice(ctx, ofp.Flows{Items: toDelete}, &flowMetadata)
-		} else {
-			respChnls = agent.deleteFlowsAndGroupsFromDevices(ctx, deviceRules, &flowMetadata)
-		}
-
-		// Wait for the responses
-		go func() {
-			// Wait for completion
-			if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
-				logger.Errorw("failure-updating-device-flows", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
-				// TODO: Revert the flow deletion
-			}
-		}()
-	}
-	//TODO: send announcement on delete
-	return nil
-}
-
 func (agent *LogicalAgent) deleteFlowAndUpdateMeterStats(ctx context.Context, mod *ofp.OfpFlowMod, chunk *FlowChunk) error {
 	chunk.lock.Lock()
 	defer chunk.lock.Unlock()
@@ -1197,22 +312,6 @@
 	return responses
 }
 
-// getUNILogicalPortNo returns the UNI logical port number specified in the flow
-func (agent *LogicalAgent) getUNILogicalPortNo(flow *ofp.OfpFlowStats) (uint32, error) {
-	var uniPort uint32
-	inPortNo := fu.GetInPort(flow)
-	outPortNo := fu.GetOutPort(flow)
-	if agent.isNNIPort(inPortNo) {
-		uniPort = outPortNo
-	} else if agent.isNNIPort(outPortNo) {
-		uniPort = inPortNo
-	}
-	if uniPort != 0 {
-		return uniPort, nil
-	}
-	return 0, status.Errorf(codes.NotFound, "no-uni-port: %v", flow)
-}
-
 func (agent *LogicalAgent) deleteFlowsFromParentDevice(ctx context.Context, flows ofp.Flows, metadata *voltha.FlowMetadata) []coreutils.Response {
 	logger.Debugw("deleting-flows-from-parent-device", log.Fields{"logical-device-id": agent.logicalDeviceID, "flows": flows})
 	responses := make([]coreutils.Response, 0)
@@ -1240,746 +339,6 @@
 	return responses
 }
 
-//flowDeleteStrict deletes a flow from the flow table of that logical device
-func (agent *LogicalAgent) flowDeleteStrict(ctx context.Context, mod *ofp.OfpFlowMod) error {
-	logger.Debugw("flowDeleteStrict", log.Fields{"mod": mod})
-	if mod == nil {
-		return nil
-	}
-
-	flow, err := fu.FlowStatsEntryFromFlowModMessage(mod)
-	if err != nil {
-		return err
-	}
-	logger.Debugw("flow-id-in-flow-delete-strict", log.Fields{"flowID": flow.Id})
-	agent.flowLock.RLock()
-	flowChunk, ok := agent.flows[flow.Id]
-	agent.flowLock.RUnlock()
-	if !ok {
-		logger.Debugw("Skipping-flow-delete-strict-request. No-flow-found", log.Fields{"flowMod": mod})
-		return nil
-	}
-	//Release the map lock and syncronize per flow
-	flowChunk.lock.Lock()
-	defer flowChunk.lock.Unlock()
-
-	var meters []*ofp.OfpMeterEntry
-	var flowGroups []*ofp.OfpGroupEntry
-	if ofMeters, er := agent.ListLogicalDeviceMeters(ctx); er == nil {
-		meters = ofMeters.Items
-	}
-	if ofGroups, er := agent.ListLogicalDeviceFlowGroups(ctx); er == nil {
-		flowGroups = ofGroups.Items
-	}
-	if changedMeter := agent.updateFlowCountOfMeterStats(ctx, mod, flow, false); !changedMeter {
-		return fmt.Errorf("Cannot delete flow - %s. Meter update failed", flow)
-	}
-
-	var flowMetadata voltha.FlowMetadata
-	flowsToDelete := []*ofp.OfpFlowStats{flowChunk.flow}
-	if err := agent.GetMeterConfig(flowsToDelete, meters, &flowMetadata); err != nil {
-		logger.Error("meter-referred-in-flows-not-present")
-		return err
-	}
-	var respChnls []coreutils.Response
-	var partialRoute bool
-	deviceRules, err := agent.flowDecomposer.DecomposeRules(ctx, agent, ofp.Flows{Items: flowsToDelete}, ofp.FlowGroups{Items: flowGroups})
-	if err != nil {
-		// A no route error means no route exists between the ports specified in the flow. This can happen when the
-		// child device is deleted and a request to delete flows from the parent device is received
-		if !errors.Is(err, route.ErrNoRoute) {
-			logger.Errorw("unexpected-error-received", log.Fields{"flows-to-delete": flowsToDelete, "error": err})
-			return err
-		}
-		partialRoute = true
-	}
-
-	// Update the model
-	if err := agent.removeLogicalDeviceFlow(ctx, flow.Id); err != nil {
-		return err
-	}
-	// Update the devices
-	if partialRoute {
-		respChnls = agent.deleteFlowsFromParentDevice(ctx, ofp.Flows{Items: flowsToDelete}, &flowMetadata)
-	} else {
-		respChnls = agent.deleteFlowsAndGroupsFromDevices(ctx, deviceRules, &flowMetadata)
-	}
-
-	// Wait for completion
-	go func() {
-		if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
-			logger.Warnw("failure-deleting-device-flows", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
-			//TODO: Revert flow changes
-		}
-	}()
-
-	return nil
-}
-
-//flowModify modifies a flow from the flow table of that logical device
-func (agent *LogicalAgent) flowModify(mod *ofp.OfpFlowMod) error {
-	return errors.New("flowModify not implemented")
-}
-
-//flowModifyStrict deletes a flow from the flow table of that logical device
-func (agent *LogicalAgent) flowModifyStrict(mod *ofp.OfpFlowMod) error {
-	return errors.New("flowModifyStrict not implemented")
-}
-
-func (agent *LogicalAgent) groupAdd(ctx context.Context, groupMod *ofp.OfpGroupMod) error {
-	if groupMod == nil {
-		return nil
-	}
-	logger.Debugw("groupAdd", log.Fields{"GroupId": groupMod.GroupId})
-	agent.groupLock.Lock()
-	_, ok := agent.groups[groupMod.GroupId]
-	if ok {
-		agent.groupLock.Unlock()
-		return fmt.Errorf("Group %d already exists", groupMod.GroupId)
-	}
-
-	groupEntry := fu.GroupEntryFromGroupMod(groupMod)
-	groupChunk := GroupChunk{
-		group: groupEntry,
-	}
-	//add to map
-	agent.groups[groupMod.GroupId] = &groupChunk
-	groupChunk.lock.Lock()
-	defer groupChunk.lock.Unlock()
-	agent.groupLock.Unlock()
-	//add to the kv store
-	path := fmt.Sprintf("groups/%s", agent.logicalDeviceID)
-	groupID := strconv.Itoa(int(groupMod.GroupId))
-	if err := agent.clusterDataProxy.AddWithID(ctx, path, groupID, groupEntry); err != nil {
-		logger.Errorw("failed-adding-group", log.Fields{"deviceID": agent.logicalDeviceID, "groupID": groupID, "err": err})
-		agent.groupLock.Lock()
-		delete(agent.groups, groupMod.GroupId)
-		agent.groupLock.Unlock()
-		return err
-	}
-	deviceRules := fu.NewDeviceRules()
-	deviceRules.CreateEntryIfNotExist(agent.rootDeviceID)
-	fg := fu.NewFlowsAndGroups()
-	fg.AddGroup(fu.GroupEntryFromGroupMod(groupMod))
-	deviceRules.AddFlowsAndGroup(agent.rootDeviceID, fg)
-
-	logger.Debugw("rules", log.Fields{"rules for group-add": deviceRules.String()})
-
-	// Update the devices
-	respChnls := agent.addFlowsAndGroupsToDevices(ctx, deviceRules, &voltha.FlowMetadata{})
-
-	// Wait for completion
-	go func() {
-		if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
-			logger.Warnw("failure-updating-device-flows-groups", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
-			//TODO: Revert flow changes
-		}
-	}()
-	return nil
-}
-
-func (agent *LogicalAgent) groupDelete(ctx context.Context, groupMod *ofp.OfpGroupMod) error {
-	logger.Debug("groupDelete")
-	if groupMod == nil {
-		return nil
-	}
-	affectedFlows := make([]*ofp.OfpFlowStats, 0)
-	affectedGroups := make([]*ofp.OfpGroupEntry, 0)
-	var groupsChanged bool
-	groupID := groupMod.GroupId
-	var err error
-	if groupID == uint32(ofp.OfpGroup_OFPG_ALL) {
-		if err := func() error {
-			agent.groupLock.Lock()
-			defer agent.groupLock.Unlock()
-			for key, groupChunk := range agent.groups {
-				//Remove from store and cache. Do this in a one time lock allocation.
-				path := fmt.Sprintf("groups/%s/%d", agent.logicalDeviceID, key)
-				if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
-					return fmt.Errorf("couldnt-deleted-group-from-store-%s", path)
-				}
-				delete(agent.groups, groupID)
-				var flows []*ofp.OfpFlowStats
-				if flows, err = agent.deleteFlowsOfGroup(ctx, key); err != nil {
-					logger.Errorw("cannot-update-flow-for-group-delete", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "groupID": key})
-					return err
-				}
-				affectedFlows = append(affectedFlows, flows...)
-				affectedGroups = append(affectedGroups, groupChunk.group)
-			}
-			return nil
-		}(); err != nil {
-			return err
-		}
-		groupsChanged = true
-	} else {
-		agent.groupLock.RLock()
-		groupChunk, ok := agent.groups[groupID]
-		agent.groupLock.RUnlock()
-		if !ok {
-			logger.Warnw("group-not-found", log.Fields{"groupID": groupID})
-			return nil
-		}
-		groupChunk.lock.Lock()
-		defer groupChunk.lock.Unlock()
-		var flows []*ofp.OfpFlowStats
-		if flows, err = agent.deleteFlowsOfGroup(ctx, groupID); err != nil {
-			logger.Errorw("cannot-update-flow-for-group-delete", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "groupID": groupID})
-			return err
-		}
-		//remove from store
-		if err := agent.removeLogicalDeviceFlowGroup(ctx, groupID); err != nil {
-			return err
-		}
-		affectedFlows = append(affectedFlows, flows...)
-		affectedGroups = append(affectedGroups, groupChunk.group)
-		groupsChanged = true
-
-	}
-
-	if err != nil || groupsChanged {
-		var deviceRules *fu.DeviceRules
-		deviceRules, err = agent.flowDecomposer.DecomposeRules(ctx, agent, ofp.Flows{Items: affectedFlows}, ofp.FlowGroups{Items: affectedGroups})
-		if err != nil {
-			return err
-		}
-		logger.Debugw("rules", log.Fields{"rules": deviceRules.String()})
-
-		// Update the devices
-		respChnls := agent.updateFlowsAndGroupsOfDevice(ctx, deviceRules, nil)
-
-		// Wait for completion
-		go func() {
-			if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
-				logger.Warnw("failure-updating-device-flows-groups", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
-				//TODO: Revert flow changes
-			}
-		}()
-	}
-	return nil
-}
-
-func (agent *LogicalAgent) deleteFlowsOfGroup(ctx context.Context, groupID uint32) ([]*ofp.OfpFlowStats, error) {
-	logger.Infow("Delete-flows-matching-group", log.Fields{"groupID": groupID})
-	var flowsRemoved []*ofp.OfpFlowStats
-	agent.flowLock.Lock()
-	defer agent.flowLock.Unlock()
-	for flowID, flowChunk := range agent.flows {
-		if fu.FlowHasOutGroup(flowChunk.flow, groupID) {
-			path := fmt.Sprintf("logical_flows/%s/%d", agent.logicalDeviceID, flowID)
-			if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
-				return nil, fmt.Errorf("couldnt-delete-flow-from-store-%s", path)
-			}
-			delete(agent.flows, flowID)
-			flowsRemoved = append(flowsRemoved, flowChunk.flow)
-		}
-	}
-	return flowsRemoved, nil
-}
-
-func (agent *LogicalAgent) groupModify(ctx context.Context, groupMod *ofp.OfpGroupMod) error {
-	logger.Debug("groupModify")
-	if groupMod == nil {
-		return nil
-	}
-
-	groupID := groupMod.GroupId
-	agent.groupLock.RLock()
-	groupChunk, ok := agent.groups[groupID]
-	agent.groupLock.RUnlock()
-	if !ok {
-		return fmt.Errorf("group-absent:%d", groupID)
-	}
-	//Don't let any other thread to make modifications to this group till all done here.
-	groupChunk.lock.Lock()
-	defer groupChunk.lock.Unlock()
-	//replace existing group entry with new group definition
-	groupEntry := fu.GroupEntryFromGroupMod(groupMod)
-	deviceRules := fu.NewDeviceRules()
-	deviceRules.CreateEntryIfNotExist(agent.rootDeviceID)
-	fg := fu.NewFlowsAndGroups()
-	fg.AddGroup(fu.GroupEntryFromGroupMod(groupMod))
-	deviceRules.AddFlowsAndGroup(agent.rootDeviceID, fg)
-
-	logger.Debugw("rules", log.Fields{"rules-for-group-modify": deviceRules.String()})
-	//update KV
-	if err := agent.updateLogicalDeviceFlowGroup(ctx, groupEntry, groupChunk); err != nil {
-		logger.Errorw("Cannot-update-logical-group", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
-		return err
-	}
-
-	// Update the devices
-	respChnls := agent.updateFlowsAndGroupsOfDevice(ctx, deviceRules, &voltha.FlowMetadata{})
-
-	// Wait for completion
-	go func() {
-		if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
-			logger.Warnw("failure-updating-device-flows-groups", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
-			//TODO: Revert flow changes
-		}
-	}()
-	return nil
-}
-
-// deleteLogicalPort removes the logical port
-func (agent *LogicalAgent) deleteLogicalPort(ctx context.Context, lPort *voltha.LogicalPort) error {
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return err
-	}
-	defer agent.requestQueue.RequestComplete()
-
-	logicalDevice := agent.getLogicalDeviceWithoutLock()
-
-	index := -1
-	for i, logicalPort := range logicalDevice.Ports {
-		if logicalPort.Id == lPort.Id {
-			index = i
-			break
-		}
-	}
-	if index >= 0 {
-		clonedPorts := clonePorts(logicalDevice.Ports)
-		if index < len(clonedPorts)-1 {
-			copy(clonedPorts[index:], clonedPorts[index+1:])
-		}
-		clonedPorts[len(clonedPorts)-1] = nil
-		clonedPorts = clonedPorts[:len(clonedPorts)-1]
-		logger.Debugw("logical-port-deleted", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
-		if err := agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, clonedPorts); err != nil {
-			logger.Errorw("logical-device-update-failed", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
-			return err
-		}
-
-		// Remove the logical port from cache
-		agent.deleteLogicalPortsFromMap([]uint32{lPort.DevicePortNo})
-		// Reset the logical device routes
-		go func() {
-			if err := agent.buildRoutes(context.Background()); err != nil {
-				logger.Warnw("device-routes-not-ready", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "error": err})
-			}
-		}()
-	}
-	return nil
-}
-
-// deleteLogicalPorts removes the logical ports associated with that deviceId
-func (agent *LogicalAgent) deleteLogicalPorts(ctx context.Context, deviceID string) error {
-	logger.Debugw("deleting-logical-ports", log.Fields{"device-id": deviceID})
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return err
-	}
-	defer agent.requestQueue.RequestComplete()
-
-	logicalDevice := agent.getLogicalDeviceWithoutLock()
-	lPortstoKeep := []*voltha.LogicalPort{}
-	lPortsNoToDelete := []uint32{}
-	for _, logicalPort := range logicalDevice.Ports {
-		if logicalPort.DeviceId != deviceID {
-			lPortstoKeep = append(lPortstoKeep, logicalPort)
-		} else {
-			lPortsNoToDelete = append(lPortsNoToDelete, logicalPort.DevicePortNo)
-		}
-	}
-	logger.Debugw("deleted-logical-ports", log.Fields{"ports": lPortstoKeep})
-	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, lPortstoKeep); err != nil {
-		logger.Errorw("logical-device-update-failed", log.Fields{"logical-device-id": agent.logicalDeviceID})
-		return err
-	}
-	// Remove the port from the cached logical ports set
-	agent.deleteLogicalPortsFromMap(lPortsNoToDelete)
-
-	// Reset the logical device routes
-	go func() {
-		if err := agent.buildRoutes(context.Background()); err != nil {
-			logger.Warnw("routes-not-ready", log.Fields{"logical-device-id": agent.logicalDeviceID, "error": err})
-		}
-	}()
-
-	return nil
-}
-
-// enableLogicalPort enables the logical port
-func (agent *LogicalAgent) enableLogicalPort(ctx context.Context, lPortID string) error {
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return err
-	}
-	defer agent.requestQueue.RequestComplete()
-
-	logicalDevice := agent.getLogicalDeviceWithoutLock()
-
-	index := -1
-	for i, logicalPort := range logicalDevice.Ports {
-		if logicalPort.Id == lPortID {
-			index = i
-			break
-		}
-	}
-	if index >= 0 {
-		clonedPorts := clonePorts(logicalDevice.Ports)
-		clonedPorts[index].OfpPort.Config = clonedPorts[index].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-		return agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, clonedPorts)
-	}
-	return status.Errorf(codes.NotFound, "Port %s on Logical Device %s", lPortID, agent.logicalDeviceID)
-}
-
-// disableLogicalPort disabled the logical port
-func (agent *LogicalAgent) disableLogicalPort(ctx context.Context, lPortID string) error {
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return err
-	}
-	defer agent.requestQueue.RequestComplete()
-
-	// Get the most up to date logical device
-	logicalDevice := agent.getLogicalDeviceWithoutLock()
-	index := -1
-	for i, logicalPort := range logicalDevice.Ports {
-		if logicalPort.Id == lPortID {
-			index = i
-			break
-		}
-	}
-	if index >= 0 {
-		clonedPorts := clonePorts(logicalDevice.Ports)
-		clonedPorts[index].OfpPort.Config = (clonedPorts[index].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)) | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-		return agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, clonedPorts)
-	}
-	return status.Errorf(codes.NotFound, "Port %s on Logical Device %s", lPortID, agent.logicalDeviceID)
-}
-
-func (agent *LogicalAgent) getPreCalculatedRoute(ingress, egress uint32) ([]route.Hop, error) {
-	logger.Debugw("ROUTE", log.Fields{"len": len(agent.deviceRoutes.Routes)})
-	for routeLink, route := range agent.deviceRoutes.Routes {
-		logger.Debugw("ROUTELINKS", log.Fields{"ingress": ingress, "egress": egress, "routelink": routeLink})
-		if ingress == routeLink.Ingress && egress == routeLink.Egress {
-			return route, nil
-		}
-	}
-	return nil, status.Errorf(codes.FailedPrecondition, "no route from:%d to:%d", ingress, egress)
-}
-
-// GetRoute returns route
-func (agent *LogicalAgent) GetRoute(ctx context.Context, ingressPortNo uint32, egressPortNo uint32) ([]route.Hop, error) {
-	logger.Debugw("getting-route", log.Fields{"ingress-port": ingressPortNo, "egress-port": egressPortNo})
-	routes := make([]route.Hop, 0)
-
-	// Note: A port value of 0 is equivalent to a nil port
-
-	//	Consider different possibilities
-	if egressPortNo != 0 && ((egressPortNo & 0x7fffffff) == uint32(ofp.OfpPortNo_OFPP_CONTROLLER)) {
-		logger.Debugw("controller-flow", log.Fields{"ingressPortNo": ingressPortNo, "egressPortNo": egressPortNo, "logicalPortsNo": agent.logicalPortsNo})
-		if agent.isNNIPort(ingressPortNo) {
-			//This is a trap on the NNI Port
-			if len(agent.deviceRoutes.Routes) == 0 {
-				// If there are no routes set (usually when the logical device has only NNI port(s), then just return an
-				// route with same IngressHop and EgressHop
-				hop := route.Hop{DeviceID: agent.rootDeviceID, Ingress: ingressPortNo, Egress: ingressPortNo}
-				routes = append(routes, hop)
-				routes = append(routes, hop)
-				return routes, nil
-			}
-			//Return a 'half' route to make the flow decomposer logic happy
-			for routeLink, path := range agent.deviceRoutes.Routes {
-				if agent.isNNIPort(routeLink.Egress) {
-					routes = append(routes, route.Hop{}) // first hop is set to empty
-					routes = append(routes, path[1])
-					return routes, nil
-				}
-			}
-			return nil, fmt.Errorf("no upstream route from:%d to:%d :%w", ingressPortNo, egressPortNo, route.ErrNoRoute)
-		}
-		//treat it as if the output port is the first NNI of the OLT
-		var err error
-		if egressPortNo, err = agent.getFirstNNIPort(); err != nil {
-			logger.Warnw("no-nni-port", log.Fields{"error": err})
-			return nil, err
-		}
-	}
-	//If ingress port is not specified (nil), it may be a wildcarded
-	//route if egress port is OFPP_CONTROLLER or a nni logical port,
-	//in which case we need to create a half-route where only the egress
-	//hop is filled, the first hop is nil
-	if ingressPortNo == 0 && agent.isNNIPort(egressPortNo) {
-		// We can use the 2nd hop of any upstream route, so just find the first upstream:
-		for routeLink, path := range agent.deviceRoutes.Routes {
-			if agent.isNNIPort(routeLink.Egress) {
-				routes = append(routes, route.Hop{}) // first hop is set to empty
-				routes = append(routes, path[1])
-				return routes, nil
-			}
-		}
-		return nil, fmt.Errorf("no upstream route from:%d to:%d :%w", ingressPortNo, egressPortNo, route.ErrNoRoute)
-	}
-	//If egress port is not specified (nil), we can also can return a "half" route
-	if egressPortNo == 0 {
-		for routeLink, path := range agent.deviceRoutes.Routes {
-			if routeLink.Ingress == ingressPortNo {
-				routes = append(routes, path[0])
-				routes = append(routes, route.Hop{})
-				return routes, nil
-			}
-		}
-		return nil, fmt.Errorf("no downstream route from:%d to:%d :%w", ingressPortNo, egressPortNo, route.ErrNoRoute)
-	}
-	//	Return the pre-calculated route
-	return agent.getPreCalculatedRoute(ingressPortNo, egressPortNo)
-}
-
-//GetWildcardInputPorts filters out the logical port number from the set of logical ports on the device and
-//returns their port numbers.  This function is invoked only during flow decomposition where the lock on the logical
-//device is already held.  Therefore it is safe to retrieve the logical device without lock.
-func (agent *LogicalAgent) GetWildcardInputPorts(excludePort ...uint32) []uint32 {
-	lPorts := make([]uint32, 0)
-	var exclPort uint32
-	if len(excludePort) == 1 {
-		exclPort = excludePort[0]
-	}
-	lDevice := agent.getLogicalDeviceWithoutLock()
-	for _, port := range lDevice.Ports {
-		if port.OfpPort.PortNo != exclPort {
-			lPorts = append(lPorts, port.OfpPort.PortNo)
-		}
-	}
-	return lPorts
-}
-
-// GetDeviceRoutes returns device graph
-func (agent *LogicalAgent) GetDeviceRoutes() *route.DeviceRoutes {
-	return agent.deviceRoutes
-}
-
-//rebuildRoutes rebuilds the device routes
-func (agent *LogicalAgent) buildRoutes(ctx context.Context) error {
-	logger.Debugf("building-routes", log.Fields{"logical-device-id": agent.logicalDeviceID})
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return err
-	}
-	defer agent.requestQueue.RequestComplete()
-
-	if agent.deviceRoutes == nil {
-		agent.deviceRoutes = route.NewDeviceRoutes(agent.logicalDeviceID, agent.deviceMgr.getDevice)
-	}
-	// Get all the logical ports on that logical device
-	lDevice := agent.getLogicalDeviceWithoutLock()
-
-	if err := agent.deviceRoutes.ComputeRoutes(ctx, lDevice.Ports); err != nil {
-		return err
-	}
-	if err := agent.deviceRoutes.Print(); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-//updateRoutes updates the device routes
-func (agent *LogicalAgent) updateRoutes(ctx context.Context, lp *voltha.LogicalPort) error {
-	logger.Debugw("updateRoutes", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return err
-	}
-	defer agent.requestQueue.RequestComplete()
-
-	if agent.deviceRoutes == nil {
-		agent.deviceRoutes = route.NewDeviceRoutes(agent.logicalDeviceID, agent.deviceMgr.getDevice)
-	}
-	if err := agent.deviceRoutes.AddPort(ctx, lp, agent.logicalDevice.Ports); err != nil {
-		return err
-	}
-	if err := agent.deviceRoutes.Print(); err != nil {
-		return err
-	}
-	return nil
-}
-
-// diff go over two lists of logical ports and return what's new, what's changed and what's removed.
-func diff(oldList, newList []*voltha.LogicalPort) (newPorts, changedPorts, deletedPorts map[string]*voltha.LogicalPort) {
-	newPorts = make(map[string]*voltha.LogicalPort, len(newList))
-	changedPorts = make(map[string]*voltha.LogicalPort, len(oldList))
-	deletedPorts = make(map[string]*voltha.LogicalPort, len(oldList))
-
-	for _, n := range newList {
-		newPorts[n.Id] = n
-	}
-
-	for _, o := range oldList {
-		if n, have := newPorts[o.Id]; have {
-			delete(newPorts, o.Id) // not new
-			if !proto.Equal(n, o) {
-				changedPorts[n.Id] = n // changed
-			}
-		} else {
-			deletedPorts[o.Id] = o // deleted
-		}
-	}
-
-	return newPorts, changedPorts, deletedPorts
-}
-
-// portUpdated is invoked when a port is updated on the logical device
-func (agent *LogicalAgent) portUpdated(prevPorts, currPorts []*voltha.LogicalPort) interface{} {
-	// Get the difference between the two list
-	newPorts, changedPorts, deletedPorts := diff(prevPorts, currPorts)
-
-	// Send the port change events to the OF controller
-	for _, newP := range newPorts {
-		go agent.ldeviceMgr.SendChangeEvent(agent.logicalDeviceID,
-			&ofp.OfpPortStatus{Reason: ofp.OfpPortReason_OFPPR_ADD, Desc: newP.OfpPort})
-	}
-	for _, change := range changedPorts {
-		go agent.ldeviceMgr.SendChangeEvent(agent.logicalDeviceID,
-			&ofp.OfpPortStatus{Reason: ofp.OfpPortReason_OFPPR_MODIFY, Desc: change.OfpPort})
-	}
-	for _, del := range deletedPorts {
-		go agent.ldeviceMgr.SendChangeEvent(agent.logicalDeviceID,
-			&ofp.OfpPortStatus{Reason: ofp.OfpPortReason_OFPPR_DELETE, Desc: del.OfpPort})
-	}
-
-	return nil
-}
-
-// addNNILogicalPort adds an NNI port to the logical device.  It returns a bool representing whether a port has been
-// added and an eror in case a valid error is encountered. If the port was successfully added it will return
-// (true, nil).   If the device is not in the correct state it will return (false, nil) as this is a valid
-// scenario. This also applies to the case where the port was already added.
-func (agent *LogicalAgent) addNNILogicalPort(ctx context.Context, device *voltha.Device, port *voltha.Port) (bool, error) {
-	logger.Debugw("addNNILogicalPort", log.Fields{"NNI": port})
-
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return false, err
-	}
-	if agent.portExist(device, port) {
-		logger.Debugw("port-already-exist", log.Fields{"port": port})
-		agent.requestQueue.RequestComplete()
-		return false, nil
-	}
-	agent.requestQueue.RequestComplete()
-
-	var portCap *ic.PortCapability
-	var err error
-	// First get the port capability
-	if portCap, err = agent.deviceMgr.getPortCapability(ctx, device.Id, port.PortNo); err != nil {
-		logger.Errorw("error-retrieving-port-capabilities", log.Fields{"error": err})
-		return false, err
-	}
-
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return false, err
-	}
-
-	defer agent.requestQueue.RequestComplete()
-	// Double check again if this port has been already added since the getPortCapability could have taken a long time
-	if agent.portExist(device, port) {
-		logger.Debugw("port-already-exist", log.Fields{"port": port})
-		return false, nil
-	}
-
-	portCap.Port.RootPort = true
-	lp := (proto.Clone(portCap.Port)).(*voltha.LogicalPort)
-	lp.DeviceId = device.Id
-	lp.Id = fmt.Sprintf("nni-%d", port.PortNo)
-	lp.OfpPort.PortNo = port.PortNo
-	lp.OfpPort.Name = lp.Id
-	lp.DevicePortNo = port.PortNo
-
-	ld := agent.getLogicalDeviceWithoutLock()
-
-	clonedPorts := clonePorts(ld.Ports)
-	if clonedPorts == nil {
-		clonedPorts = make([]*voltha.LogicalPort, 0)
-	}
-	clonedPorts = append(clonedPorts, lp)
-
-	if err = agent.updateLogicalDevicePortsWithoutLock(ctx, ld, clonedPorts); err != nil {
-		logger.Errorw("error-updating-logical-device", log.Fields{"error": err})
-		return false, err
-	}
-
-	// Update the device routes with this new logical port
-	clonedLP := (proto.Clone(lp)).(*voltha.LogicalPort)
-	go func() {
-		if err := agent.updateRoutes(context.Background(), clonedLP); err != nil {
-			logger.Warnw("routes-not-ready", log.Fields{"logical-device-id": agent.logicalDeviceID, "logical-port": lp.OfpPort.PortNo, "error": err})
-		}
-	}()
-
-	return true, nil
-}
-
-func (agent *LogicalAgent) portExist(device *voltha.Device, port *voltha.Port) bool {
-	ldevice := agent.getLogicalDeviceWithoutLock()
-	for _, lPort := range ldevice.Ports {
-		if lPort.DeviceId == device.Id && lPort.DevicePortNo == port.PortNo && lPort.Id == port.Label {
-			return true
-		}
-	}
-	return false
-}
-
-// addUNILogicalPort adds an UNI port to the logical device.  It returns a bool representing whether a port has been
-// added and an eror in case a valid error is encountered. If the port was successfully added it will return
-// (true, nil).   If the device is not in the correct state it will return (false, nil) as this is a valid
-// scenario. This also applies to the case where the port was already added.
-func (agent *LogicalAgent) addUNILogicalPort(ctx context.Context, childDevice *voltha.Device, port *voltha.Port) (bool, error) {
-	logger.Debugw("addUNILogicalPort", log.Fields{"port": port})
-	if childDevice.AdminState != voltha.AdminState_ENABLED || childDevice.OperStatus != voltha.OperStatus_ACTIVE {
-		logger.Infow("device-not-ready", log.Fields{"deviceId": childDevice.Id, "admin": childDevice.AdminState, "oper": childDevice.OperStatus})
-		return false, nil
-	}
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return false, err
-	}
-
-	if agent.portExist(childDevice, port) {
-		logger.Debugw("port-already-exist", log.Fields{"port": port})
-		agent.requestQueue.RequestComplete()
-		return false, nil
-	}
-	agent.requestQueue.RequestComplete()
-	var portCap *ic.PortCapability
-	var err error
-	// First get the port capability
-	if portCap, err = agent.deviceMgr.getPortCapability(ctx, childDevice.Id, port.PortNo); err != nil {
-		logger.Errorw("error-retrieving-port-capabilities", log.Fields{"error": err})
-		return false, err
-	}
-	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
-		return false, err
-	}
-	defer agent.requestQueue.RequestComplete()
-	// Double check again if this port has been already added since the getPortCapability could have taken a long time
-	if agent.portExist(childDevice, port) {
-		logger.Debugw("port-already-exist", log.Fields{"port": port})
-		return false, nil
-	}
-	// Get stored logical device
-	ldevice := agent.getLogicalDeviceWithoutLock()
-
-	logger.Debugw("adding-uni", log.Fields{"deviceId": childDevice.Id})
-	portCap.Port.RootPort = false
-	portCap.Port.Id = port.Label
-	portCap.Port.OfpPort.PortNo = port.PortNo
-	portCap.Port.DeviceId = childDevice.Id
-	portCap.Port.DevicePortNo = port.PortNo
-	clonedPorts := clonePorts(ldevice.Ports)
-	if clonedPorts == nil {
-		clonedPorts = make([]*voltha.LogicalPort, 0)
-	}
-	clonedPorts = append(clonedPorts, portCap.Port)
-	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, ldevice, clonedPorts); err != nil {
-		return false, err
-	}
-	// Update the device graph with this new logical port
-	clonedLP := (proto.Clone(portCap.Port)).(*voltha.LogicalPort)
-
-	go func() {
-		if err := agent.updateRoutes(context.Background(), clonedLP); err != nil {
-			logger.Warn("routes-not-ready", log.Fields{"logical-device-id": agent.logicalDeviceID, "error": err})
-		}
-	}()
-
-	return true, nil
-}
-
 func (agent *LogicalAgent) packetOut(ctx context.Context, packet *ofp.OfpPacketOut) {
 	logger.Debugw("packet-out", log.Fields{
 		"packet": hex.EncodeToString(packet.Data),
@@ -2003,120 +362,3 @@
 	agent.ldeviceMgr.SendPacketIn(agent.logicalDeviceID, transactionID, packetIn)
 	logger.Debugw("sending-packet-in", log.Fields{"packet": hex.EncodeToString(packetIn.Data)})
 }
-
-func (agent *LogicalAgent) addLogicalPortToMap(portNo uint32, nniPort bool) {
-	agent.lockLogicalPortsNo.Lock()
-	defer agent.lockLogicalPortsNo.Unlock()
-	if exist := agent.logicalPortsNo[portNo]; !exist {
-		agent.logicalPortsNo[portNo] = nniPort
-	}
-}
-
-func (agent *LogicalAgent) deleteLogicalPortsFromMap(portsNo []uint32) {
-	agent.lockLogicalPortsNo.Lock()
-	defer agent.lockLogicalPortsNo.Unlock()
-	for _, pNo := range portsNo {
-		delete(agent.logicalPortsNo, pNo)
-	}
-}
-
-func (agent *LogicalAgent) addLogicalPortsToMap(lps []*voltha.LogicalPort) {
-	agent.lockLogicalPortsNo.Lock()
-	defer agent.lockLogicalPortsNo.Unlock()
-	for _, lp := range lps {
-		if exist := agent.logicalPortsNo[lp.DevicePortNo]; !exist {
-			agent.logicalPortsNo[lp.DevicePortNo] = lp.RootPort
-		}
-	}
-}
-
-func (agent *LogicalAgent) loadFlows(ctx context.Context) {
-	agent.flowLock.Lock()
-	defer agent.flowLock.Unlock()
-
-	var flowList []*ofp.OfpFlowStats
-	if err := agent.clusterDataProxy.List(ctx, "logical_flows/"+agent.logicalDeviceID, &flowList); err != nil {
-		logger.Errorw("Failed-to-list-logicalflows-from-cluster-data-proxy", log.Fields{"error": err})
-		return
-	}
-	for _, flow := range flowList {
-		if flow != nil {
-			flowsChunk := FlowChunk{
-				flow: flow,
-			}
-			agent.flows[flow.Id] = &flowsChunk
-		}
-	}
-}
-
-func (agent *LogicalAgent) loadMeters(ctx context.Context) {
-	agent.meterLock.Lock()
-	defer agent.meterLock.Unlock()
-
-	var meters []*ofp.OfpMeterEntry
-	if err := agent.clusterDataProxy.List(ctx, "meters/"+agent.logicalDeviceID, &meters); err != nil {
-		logger.Errorw("Failed-to-list-meters-from-proxy", log.Fields{"error": err})
-		return
-	}
-	for _, meter := range meters {
-		if meter.Config != nil {
-			meterChunk := MeterChunk{
-				meter: meter,
-			}
-			agent.meters[meter.Config.MeterId] = &meterChunk
-		}
-	}
-}
-
-func (agent *LogicalAgent) loadGroups(ctx context.Context) {
-	agent.groupLock.Lock()
-	defer agent.groupLock.Unlock()
-
-	var groups []*ofp.OfpGroupEntry
-	if err := agent.clusterDataProxy.List(ctx, "groups/"+agent.logicalDeviceID, &groups); err != nil {
-		logger.Errorw("Failed-to-list-groups-from-proxy", log.Fields{"error": err})
-		return
-	}
-	for _, group := range groups {
-		if group.Desc != nil {
-			groupChunk := GroupChunk{
-				group: group,
-			}
-			agent.groups[group.Desc.GroupId] = &groupChunk
-		}
-	}
-	logger.Infow("Groups-are-loaded-into-the-cache-from-store", log.Fields{"logicalDeviceID": agent.logicalDeviceID})
-}
-
-func (agent *LogicalAgent) isNNIPort(portNo uint32) bool {
-	agent.lockLogicalPortsNo.RLock()
-	defer agent.lockLogicalPortsNo.RUnlock()
-	if exist := agent.logicalPortsNo[portNo]; exist {
-		return agent.logicalPortsNo[portNo]
-	}
-	return false
-}
-
-func (agent *LogicalAgent) getFirstNNIPort() (uint32, error) {
-	agent.lockLogicalPortsNo.RLock()
-	defer agent.lockLogicalPortsNo.RUnlock()
-	for portNo, nni := range agent.logicalPortsNo {
-		if nni {
-			return portNo, nil
-		}
-	}
-	return 0, status.Error(codes.NotFound, "No NNI port found")
-}
-
-//GetNNIPorts returns NNI ports.
-func (agent *LogicalAgent) GetNNIPorts() []uint32 {
-	agent.lockLogicalPortsNo.RLock()
-	defer agent.lockLogicalPortsNo.RUnlock()
-	nniPorts := make([]uint32, 0)
-	for portNo, nni := range agent.logicalPortsNo {
-		if nni {
-			nniPorts = append(nniPorts, portNo)
-		}
-	}
-	return nniPorts
-}
diff --git a/rw_core/core/device/logical_agent_flow.go b/rw_core/core/device/logical_agent_flow.go
new file mode 100644
index 0000000..5d35251
--- /dev/null
+++ b/rw_core/core/device/logical_agent_flow.go
@@ -0,0 +1,405 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package device
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"strconv"
+
+	"github.com/gogo/protobuf/proto"
+	"github.com/opencord/voltha-go/rw_core/route"
+	coreutils "github.com/opencord/voltha-go/rw_core/utils"
+	fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+//updateFlowTable updates the flow table of that logical device
+func (agent *LogicalAgent) updateFlowTable(ctx context.Context, flow *ofp.OfpFlowMod) error {
+	logger.Debug("UpdateFlowTable")
+	if flow == nil {
+		return nil
+	}
+
+	if err := agent.generateDeviceRoutesIfNeeded(ctx); err != nil {
+		return err
+	}
+	switch flow.GetCommand() {
+	case ofp.OfpFlowModCommand_OFPFC_ADD:
+		return agent.flowAdd(ctx, flow)
+	case ofp.OfpFlowModCommand_OFPFC_DELETE:
+		return agent.flowDelete(ctx, flow)
+	case ofp.OfpFlowModCommand_OFPFC_DELETE_STRICT:
+		return agent.flowDeleteStrict(ctx, flow)
+	case ofp.OfpFlowModCommand_OFPFC_MODIFY:
+		return agent.flowModify(flow)
+	case ofp.OfpFlowModCommand_OFPFC_MODIFY_STRICT:
+		return agent.flowModifyStrict(flow)
+	}
+	return status.Errorf(codes.Internal,
+		"unhandled-command: lDeviceId:%s, command:%s", agent.logicalDeviceID, flow.GetCommand())
+}
+
+//flowAdd adds a flow to the flow table of that logical device
+func (agent *LogicalAgent) flowAdd(ctx context.Context, mod *ofp.OfpFlowMod) error {
+	logger.Debugw("flowAdd", log.Fields{"flow": mod})
+	if mod == nil {
+		return nil
+	}
+	flow, err := fu.FlowStatsEntryFromFlowModMessage(mod)
+	if err != nil {
+		logger.Errorw("flowAdd-failed", log.Fields{"flowMod": mod, "err": err})
+		return err
+	}
+	var updated bool
+	var changed bool
+	if changed, updated, err = agent.decomposeAndAdd(ctx, flow, mod); err != nil {
+		logger.Errorw("flow-decompose-and-add-failed ", log.Fields{"flowMod": mod, "err": err})
+		return err
+	}
+	if changed && !updated {
+		if dbupdated := agent.updateFlowCountOfMeterStats(ctx, mod, flow, false); !dbupdated {
+			return fmt.Errorf("couldnt-updated-flow-stats-%s", strconv.FormatUint(flow.Id, 10))
+		}
+	}
+	return nil
+
+}
+
+func (agent *LogicalAgent) decomposeAndAdd(ctx context.Context, flow *ofp.OfpFlowStats, mod *ofp.OfpFlowMod) (bool, bool, error) {
+	changed := false
+	updated := false
+	alreadyExist := true
+	var flowToReplace *ofp.OfpFlowStats
+
+	//if flow is not found in the map, create a new entry, otherwise get the existing one.
+	agent.flowLock.Lock()
+	flowChunk, ok := agent.flows[flow.Id]
+	if !ok {
+		flowChunk = &FlowChunk{
+			flow: flow,
+		}
+		agent.flows[flow.Id] = flowChunk
+		alreadyExist = false
+		flowChunk.lock.Lock() //acquire chunk lock before releasing map lock
+		defer flowChunk.lock.Unlock()
+		agent.flowLock.Unlock()
+	} else {
+		agent.flowLock.Unlock() //release map lock before acquiring chunk lock
+		flowChunk.lock.Lock()
+		defer flowChunk.lock.Unlock()
+	}
+
+	if !alreadyExist {
+		flowID := strconv.FormatUint(flow.Id, 10)
+		if err := agent.clusterDataProxy.AddWithID(ctx, "logical_flows/"+agent.logicalDeviceID, flowID, flow); err != nil {
+			logger.Errorw("failed-adding-flow-to-db", log.Fields{"deviceID": agent.logicalDeviceID, "flowID": flowID, "err": err})
+			//Revert the map
+			//TODO: Solve the condition:If we have two flow Adds of the same flow (at least same priority and match) in quick succession
+			//then if the first one fails while the second one was waiting on the flowchunk, we will end up with an instance of flowChunk that is no longer in the map.
+			agent.flowLock.Lock()
+			delete(agent.flows, flow.Id)
+			agent.flowLock.Unlock()
+			return changed, updated, err
+		}
+	}
+	flows := make([]*ofp.OfpFlowStats, 0)
+	updatedFlows := make([]*ofp.OfpFlowStats, 0)
+	checkOverlap := (mod.Flags & uint32(ofp.OfpFlowModFlags_OFPFF_CHECK_OVERLAP)) != 0
+	if checkOverlap {
+		if overlapped := fu.FindOverlappingFlows(flows, mod); len(overlapped) != 0 {
+			//	TODO:  should this error be notified other than being logged?
+			logger.Warnw("overlapped-flows", log.Fields{"logicaldeviceId": agent.logicalDeviceID})
+		} else {
+			//	Add flow
+			changed = true
+		}
+	} else {
+		if alreadyExist {
+			flowToReplace = flowChunk.flow
+			if (mod.Flags & uint32(ofp.OfpFlowModFlags_OFPFF_RESET_COUNTS)) != 0 {
+				flow.ByteCount = flowToReplace.ByteCount
+				flow.PacketCount = flowToReplace.PacketCount
+			}
+			if !proto.Equal(flowToReplace, flow) {
+				changed = true
+				updated = true
+			}
+		} else {
+			changed = true
+		}
+	}
+	logger.Debugw("flowAdd-changed", log.Fields{"changed": changed, "updated": updated})
+	if changed {
+		updatedFlows = append(updatedFlows, flow)
+		var flowMetadata voltha.FlowMetadata
+		lMeters, _ := agent.ListLogicalDeviceMeters(ctx)
+		if err := agent.GetMeterConfig(updatedFlows, lMeters.Items, &flowMetadata); err != nil {
+			logger.Error("Meter-referred-in-flow-not-present")
+			return changed, updated, err
+		}
+		flowGroups, _ := agent.ListLogicalDeviceFlowGroups(ctx)
+		deviceRules, err := agent.flowDecomposer.DecomposeRules(ctx, agent, ofp.Flows{Items: updatedFlows}, *flowGroups)
+		if err != nil {
+			return changed, updated, err
+		}
+
+		logger.Debugw("rules", log.Fields{"rules": deviceRules.String()})
+		//	Update store and cache
+		if updated {
+			if err := agent.updateLogicalDeviceFlow(ctx, flow, flowChunk); err != nil {
+				return changed, updated, err
+			}
+		}
+		respChannels := agent.addFlowsAndGroupsToDevices(ctx, deviceRules, &flowMetadata)
+		// Create the go routines to wait
+		go func() {
+			// Wait for completion
+			if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChannels...); res != nil {
+				logger.Infow("failed-to-add-flows-will-attempt-deletion", log.Fields{"errors": res, "logical-device-id": agent.logicalDeviceID})
+				// Revert added flows
+				if err := agent.revertAddedFlows(context.Background(), mod, flow, flowToReplace, deviceRules, &flowMetadata); err != nil {
+					logger.Errorw("failure-to-delete-flows-after-failed-addition", log.Fields{"logical-device-id": agent.logicalDeviceID, "error": err})
+				}
+			}
+		}()
+	}
+	return changed, updated, nil
+}
+
+// revertAddedFlows reverts flows after the flowAdd request has failed.  All flows corresponding to that flowAdd request
+// will be reverted, both from the logical devices and the devices.
+func (agent *LogicalAgent) revertAddedFlows(ctx context.Context, mod *ofp.OfpFlowMod, addedFlow *ofp.OfpFlowStats, replacedFlow *ofp.OfpFlowStats, deviceRules *fu.DeviceRules, metadata *voltha.FlowMetadata) error {
+	logger.Debugw("revertFlowAdd", log.Fields{"added-flow": addedFlow, "replaced-flow": replacedFlow, "device-rules": deviceRules, "metadata": metadata})
+
+	agent.flowLock.RLock()
+	flowChunk, ok := agent.flows[addedFlow.Id]
+	agent.flowLock.RUnlock()
+	if !ok {
+		// Not found - do nothing
+		log.Debugw("flow-not-found", log.Fields{"added-flow": addedFlow})
+		return nil
+	}
+	//Leave the map lock and syncronize per flow
+	flowChunk.lock.Lock()
+	defer flowChunk.lock.Unlock()
+
+	if replacedFlow != nil {
+		if err := agent.updateLogicalDeviceFlow(ctx, replacedFlow, flowChunk); err != nil {
+			return err
+		}
+	} else {
+		if err := agent.removeLogicalDeviceFlow(ctx, addedFlow.Id); err != nil {
+			return err
+		}
+	}
+	// Revert meters
+	if changedMeterStats := agent.updateFlowCountOfMeterStats(ctx, mod, addedFlow, true); !changedMeterStats {
+		return fmt.Errorf("Unable-to-revert-meterstats-for-flow-%s", strconv.FormatUint(addedFlow.Id, 10))
+	}
+
+	// Update the devices
+	respChnls := agent.deleteFlowsAndGroupsFromDevices(ctx, deviceRules, metadata)
+
+	// Wait for the responses
+	go func() {
+		// Since this action is taken following an add failure, we may also receive a failure for the revert
+		if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
+			logger.Warnw("failure-reverting-added-flows", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
+		}
+	}()
+
+	return nil
+}
+
+//flowDelete deletes a flow from the flow table of that logical device
+func (agent *LogicalAgent) flowDelete(ctx context.Context, mod *ofp.OfpFlowMod) error {
+	logger.Debug("flowDelete")
+	if mod == nil {
+		return nil
+	}
+
+	fs, err := fu.FlowStatsEntryFromFlowModMessage(mod)
+	if err != nil {
+		return err
+	}
+
+	//build a list of what to delete
+	toDelete := make([]*ofp.OfpFlowStats, 0)
+	toDeleteChunks := make([]*FlowChunk, 0)
+	//Lock the map to search the matched flows
+	agent.flowLock.RLock()
+	for _, f := range agent.flows {
+		if fu.FlowMatch(f.flow, fs) {
+			toDelete = append(toDelete, f.flow)
+			toDeleteChunks = append(toDeleteChunks, f)
+			continue
+		}
+		// Check wild card match
+		if fu.FlowMatchesMod(f.flow, mod) {
+			toDelete = append(toDelete, f.flow)
+			toDeleteChunks = append(toDeleteChunks, f)
+		}
+	}
+	agent.flowLock.RUnlock()
+	//Delete the matched flows
+	if len(toDelete) > 0 {
+		logger.Debugw("flowDelete", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "toDelete": len(toDelete)})
+		var meters []*ofp.OfpMeterEntry
+		var flowGroups []*ofp.OfpGroupEntry
+		if ofpMeters, err := agent.ListLogicalDeviceMeters(ctx); err != nil {
+			meters = ofpMeters.Items
+		}
+
+		if groups, err := agent.ListLogicalDeviceFlowGroups(ctx); err != nil {
+			flowGroups = groups.Items
+		}
+
+		for _, fc := range toDeleteChunks {
+			if err := agent.deleteFlowAndUpdateMeterStats(ctx, mod, fc); err != nil {
+				return err
+			}
+		}
+		var flowMetadata voltha.FlowMetadata
+		if err := agent.GetMeterConfig(toDelete, meters, &flowMetadata); err != nil { // This should never happen
+			logger.Error("Meter-referred-in-flows-not-present")
+			return err
+		}
+		var respChnls []coreutils.Response
+		var partialRoute bool
+		var deviceRules *fu.DeviceRules
+		deviceRules, err = agent.flowDecomposer.DecomposeRules(ctx, agent, ofp.Flows{Items: toDelete}, ofp.FlowGroups{Items: flowGroups})
+		if err != nil {
+			// A no route error means no route exists between the ports specified in the flow. This can happen when the
+			// child device is deleted and a request to delete flows from the parent device is received
+			if !errors.Is(err, route.ErrNoRoute) {
+				logger.Errorw("unexpected-error-received", log.Fields{"flows-to-delete": toDelete, "error": err})
+				return err
+			}
+			partialRoute = true
+		}
+
+		// Update the devices
+		if partialRoute {
+			respChnls = agent.deleteFlowsFromParentDevice(ctx, ofp.Flows{Items: toDelete}, &flowMetadata)
+		} else {
+			respChnls = agent.deleteFlowsAndGroupsFromDevices(ctx, deviceRules, &flowMetadata)
+		}
+
+		// Wait for the responses
+		go func() {
+			// Wait for completion
+			if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
+				logger.Errorw("failure-updating-device-flows", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
+				// TODO: Revert the flow deletion
+			}
+		}()
+	}
+	//TODO: send announcement on delete
+	return nil
+}
+
+//flowDeleteStrict deletes a flow from the flow table of that logical device
+func (agent *LogicalAgent) flowDeleteStrict(ctx context.Context, mod *ofp.OfpFlowMod) error {
+	logger.Debugw("flowDeleteStrict", log.Fields{"mod": mod})
+	if mod == nil {
+		return nil
+	}
+
+	flow, err := fu.FlowStatsEntryFromFlowModMessage(mod)
+	if err != nil {
+		return err
+	}
+	logger.Debugw("flow-id-in-flow-delete-strict", log.Fields{"flowID": flow.Id})
+	agent.flowLock.RLock()
+	flowChunk, ok := agent.flows[flow.Id]
+	agent.flowLock.RUnlock()
+	if !ok {
+		logger.Debugw("Skipping-flow-delete-strict-request. No-flow-found", log.Fields{"flowMod": mod})
+		return nil
+	}
+	//Release the map lock and syncronize per flow
+	flowChunk.lock.Lock()
+	defer flowChunk.lock.Unlock()
+
+	var meters []*ofp.OfpMeterEntry
+	var flowGroups []*ofp.OfpGroupEntry
+	if ofMeters, er := agent.ListLogicalDeviceMeters(ctx); er == nil {
+		meters = ofMeters.Items
+	}
+	if ofGroups, er := agent.ListLogicalDeviceFlowGroups(ctx); er == nil {
+		flowGroups = ofGroups.Items
+	}
+	if changedMeter := agent.updateFlowCountOfMeterStats(ctx, mod, flow, false); !changedMeter {
+		return fmt.Errorf("Cannot delete flow - %s. Meter update failed", flow)
+	}
+
+	var flowMetadata voltha.FlowMetadata
+	flowsToDelete := []*ofp.OfpFlowStats{flowChunk.flow}
+	if err := agent.GetMeterConfig(flowsToDelete, meters, &flowMetadata); err != nil {
+		logger.Error("meter-referred-in-flows-not-present")
+		return err
+	}
+	var respChnls []coreutils.Response
+	var partialRoute bool
+	deviceRules, err := agent.flowDecomposer.DecomposeRules(ctx, agent, ofp.Flows{Items: flowsToDelete}, ofp.FlowGroups{Items: flowGroups})
+	if err != nil {
+		// A no route error means no route exists between the ports specified in the flow. This can happen when the
+		// child device is deleted and a request to delete flows from the parent device is received
+		if !errors.Is(err, route.ErrNoRoute) {
+			logger.Errorw("unexpected-error-received", log.Fields{"flows-to-delete": flowsToDelete, "error": err})
+			return err
+		}
+		partialRoute = true
+	}
+
+	// Update the model
+	if err := agent.removeLogicalDeviceFlow(ctx, flow.Id); err != nil {
+		return err
+	}
+	// Update the devices
+	if partialRoute {
+		respChnls = agent.deleteFlowsFromParentDevice(ctx, ofp.Flows{Items: flowsToDelete}, &flowMetadata)
+	} else {
+		respChnls = agent.deleteFlowsAndGroupsFromDevices(ctx, deviceRules, &flowMetadata)
+	}
+
+	// Wait for completion
+	go func() {
+		if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
+			logger.Warnw("failure-deleting-device-flows", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
+			//TODO: Revert flow changes
+		}
+	}()
+
+	return nil
+}
+
+//flowModify modifies a flow from the flow table of that logical device
+func (agent *LogicalAgent) flowModify(mod *ofp.OfpFlowMod) error {
+	return errors.New("flowModify not implemented")
+}
+
+//flowModifyStrict deletes a flow from the flow table of that logical device
+func (agent *LogicalAgent) flowModifyStrict(mod *ofp.OfpFlowMod) error {
+	return errors.New("flowModifyStrict not implemented")
+}
diff --git a/rw_core/core/device/logical_agent_flow_loader.go b/rw_core/core/device/logical_agent_flow_loader.go
new file mode 100644
index 0000000..84d1a47
--- /dev/null
+++ b/rw_core/core/device/logical_agent_flow_loader.go
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package device
+
+import (
+	"context"
+	"fmt"
+	"sync"
+
+	"github.com/gogo/protobuf/proto"
+	fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+//FlowChunk keeps a flow and the lock for this flow. The lock in the struct is used to syncronize the
+//modifications for the related flow.
+type FlowChunk struct {
+	flow *ofp.OfpFlowStats
+	lock sync.Mutex
+}
+
+func (agent *LogicalAgent) loadFlows(ctx context.Context) {
+	agent.flowLock.Lock()
+	defer agent.flowLock.Unlock()
+
+	var flowList []*ofp.OfpFlowStats
+	if err := agent.clusterDataProxy.List(ctx, "logical_flows/"+agent.logicalDeviceID, &flowList); err != nil {
+		logger.Errorw("Failed-to-list-logicalflows-from-cluster-data-proxy", log.Fields{"error": err})
+		return
+	}
+	for _, flow := range flowList {
+		if flow != nil {
+			flowsChunk := FlowChunk{
+				flow: flow,
+			}
+			agent.flows[flow.Id] = &flowsChunk
+		}
+	}
+}
+
+//updateLogicalDeviceFlow updates flow in the store and cache
+//It is assumed that the chunk lock has been acquired before this function is called
+func (agent *LogicalAgent) updateLogicalDeviceFlow(ctx context.Context, flow *ofp.OfpFlowStats, flowChunk *FlowChunk) error {
+	path := fmt.Sprintf("logical_flows/%s/%d", agent.logicalDeviceID, flow.Id)
+	if err := agent.clusterDataProxy.Update(ctx, path, flow); err != nil {
+		return status.Errorf(codes.Internal, "failed-update-flow:%s:%d %s", agent.logicalDeviceID, flow.Id, err)
+	}
+	flowChunk.flow = flow
+	return nil
+}
+
+//removeLogicalDeviceFlow deletes the flow from store and cache.
+//It is assumed that the chunk lock has been acquired before this function is called
+func (agent *LogicalAgent) removeLogicalDeviceFlow(ctx context.Context, flowID uint64) error {
+	path := fmt.Sprintf("logical_flows/%s/%d", agent.logicalDeviceID, flowID)
+	if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
+		return fmt.Errorf("couldnt-delete-flow-from-the-store-%s", path)
+	}
+	agent.flowLock.Lock()
+	defer agent.flowLock.Unlock()
+	delete(agent.flows, flowID)
+	return nil
+}
+
+// ListLogicalDeviceFlows returns logical device flows
+func (agent *LogicalAgent) ListLogicalDeviceFlows(ctx context.Context) (*ofp.Flows, error) {
+	logger.Debug("ListLogicalDeviceFlows")
+	var flowStats []*ofp.OfpFlowStats
+	agent.flowLock.RLock()
+	defer agent.flowLock.RUnlock()
+	for _, flowChunk := range agent.flows {
+		flowStats = append(flowStats, (proto.Clone(flowChunk.flow)).(*ofp.OfpFlowStats))
+	}
+	return &ofp.Flows{Items: flowStats}, nil
+}
+
+func (agent *LogicalAgent) deleteFlowsOfMeter(ctx context.Context, meterID uint32) error {
+	logger.Infow("Delete-flows-matching-meter", log.Fields{"meter": meterID})
+	agent.flowLock.Lock()
+	defer agent.flowLock.Unlock()
+	for flowID, flowChunk := range agent.flows {
+		if mID := fu.GetMeterIdFromFlow(flowChunk.flow); mID != 0 && mID == meterID {
+			logger.Debugw("Flow-to-be- deleted", log.Fields{"flow": flowChunk.flow})
+			path := fmt.Sprintf("logical_flows/%s/%d", agent.logicalDeviceID, flowID)
+			if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
+				//TODO: Think on carrying on and deleting the remaining flows, instead of returning.
+				//Anyways this returns an error to controller which possibly results with a re-deletion.
+				//Then how can we handle the new deletion request(Same for group deletion)?
+				return fmt.Errorf("couldnt-deleted-flow-from-store-%s", path)
+			}
+			delete(agent.flows, flowID)
+		}
+	}
+	return nil
+}
+
+func (agent *LogicalAgent) deleteFlowsOfGroup(ctx context.Context, groupID uint32) ([]*ofp.OfpFlowStats, error) {
+	logger.Infow("Delete-flows-matching-group", log.Fields{"groupID": groupID})
+	var flowsRemoved []*ofp.OfpFlowStats
+	agent.flowLock.Lock()
+	defer agent.flowLock.Unlock()
+	for flowID, flowChunk := range agent.flows {
+		if fu.FlowHasOutGroup(flowChunk.flow, groupID) {
+			path := fmt.Sprintf("logical_flows/%s/%d", agent.logicalDeviceID, flowID)
+			if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
+				return nil, fmt.Errorf("couldnt-delete-flow-from-store-%s", path)
+			}
+			delete(agent.flows, flowID)
+			flowsRemoved = append(flowsRemoved, flowChunk.flow)
+		}
+	}
+	return flowsRemoved, nil
+}
diff --git a/rw_core/core/device/logical_agent_group.go b/rw_core/core/device/logical_agent_group.go
new file mode 100644
index 0000000..a0d6c4a
--- /dev/null
+++ b/rw_core/core/device/logical_agent_group.go
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package device
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+
+	coreutils "github.com/opencord/voltha-go/rw_core/utils"
+	fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+//updateGroupTable updates the group table of that logical device
+func (agent *LogicalAgent) updateGroupTable(ctx context.Context, groupMod *ofp.OfpGroupMod) error {
+	logger.Debug("updateGroupTable")
+	if groupMod == nil {
+		return nil
+	}
+
+	if err := agent.generateDeviceRoutesIfNeeded(ctx); err != nil {
+		return err
+	}
+
+	switch groupMod.GetCommand() {
+	case ofp.OfpGroupModCommand_OFPGC_ADD:
+		return agent.groupAdd(ctx, groupMod)
+	case ofp.OfpGroupModCommand_OFPGC_DELETE:
+		return agent.groupDelete(ctx, groupMod)
+	case ofp.OfpGroupModCommand_OFPGC_MODIFY:
+		return agent.groupModify(ctx, groupMod)
+	}
+	return status.Errorf(codes.Internal, "unhandled-command: lDeviceId:%s, command:%s", agent.logicalDeviceID, groupMod.GetCommand())
+}
+
+func (agent *LogicalAgent) groupAdd(ctx context.Context, groupMod *ofp.OfpGroupMod) error {
+	if groupMod == nil {
+		return nil
+	}
+	logger.Debugw("groupAdd", log.Fields{"GroupId": groupMod.GroupId})
+	agent.groupLock.Lock()
+	_, ok := agent.groups[groupMod.GroupId]
+	if ok {
+		agent.groupLock.Unlock()
+		return fmt.Errorf("Group %d already exists", groupMod.GroupId)
+	}
+
+	groupEntry := fu.GroupEntryFromGroupMod(groupMod)
+	groupChunk := GroupChunk{
+		group: groupEntry,
+	}
+	//add to map
+	agent.groups[groupMod.GroupId] = &groupChunk
+	groupChunk.lock.Lock()
+	defer groupChunk.lock.Unlock()
+	agent.groupLock.Unlock()
+	//add to the kv store
+	path := fmt.Sprintf("groups/%s", agent.logicalDeviceID)
+	groupID := strconv.Itoa(int(groupMod.GroupId))
+	if err := agent.clusterDataProxy.AddWithID(ctx, path, groupID, groupEntry); err != nil {
+		logger.Errorw("failed-adding-group", log.Fields{"deviceID": agent.logicalDeviceID, "groupID": groupID, "err": err})
+		agent.groupLock.Lock()
+		delete(agent.groups, groupMod.GroupId)
+		agent.groupLock.Unlock()
+		return err
+	}
+	deviceRules := fu.NewDeviceRules()
+	deviceRules.CreateEntryIfNotExist(agent.rootDeviceID)
+	fg := fu.NewFlowsAndGroups()
+	fg.AddGroup(fu.GroupEntryFromGroupMod(groupMod))
+	deviceRules.AddFlowsAndGroup(agent.rootDeviceID, fg)
+
+	logger.Debugw("rules", log.Fields{"rules for group-add": deviceRules.String()})
+
+	// Update the devices
+	respChnls := agent.addFlowsAndGroupsToDevices(ctx, deviceRules, &voltha.FlowMetadata{})
+
+	// Wait for completion
+	go func() {
+		if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
+			logger.Warnw("failure-updating-device-flows-groups", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
+			//TODO: Revert flow changes
+		}
+	}()
+	return nil
+}
+
+func (agent *LogicalAgent) groupDelete(ctx context.Context, groupMod *ofp.OfpGroupMod) error {
+	logger.Debug("groupDelete")
+	if groupMod == nil {
+		return nil
+	}
+	affectedFlows := make([]*ofp.OfpFlowStats, 0)
+	affectedGroups := make([]*ofp.OfpGroupEntry, 0)
+	var groupsChanged bool
+	groupID := groupMod.GroupId
+	var err error
+	if groupID == uint32(ofp.OfpGroup_OFPG_ALL) {
+		if err := func() error {
+			agent.groupLock.Lock()
+			defer agent.groupLock.Unlock()
+			for key, groupChunk := range agent.groups {
+				//Remove from store and cache. Do this in a one time lock allocation.
+				path := fmt.Sprintf("groups/%s/%d", agent.logicalDeviceID, key)
+				if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
+					return fmt.Errorf("couldnt-deleted-group-from-store-%s", path)
+				}
+				delete(agent.groups, groupID)
+				var flows []*ofp.OfpFlowStats
+				if flows, err = agent.deleteFlowsOfGroup(ctx, key); err != nil {
+					logger.Errorw("cannot-update-flow-for-group-delete", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "groupID": key})
+					return err
+				}
+				affectedFlows = append(affectedFlows, flows...)
+				affectedGroups = append(affectedGroups, groupChunk.group)
+			}
+			return nil
+		}(); err != nil {
+			return err
+		}
+		groupsChanged = true
+	} else {
+		agent.groupLock.RLock()
+		groupChunk, ok := agent.groups[groupID]
+		agent.groupLock.RUnlock()
+		if !ok {
+			logger.Warnw("group-not-found", log.Fields{"groupID": groupID})
+			return nil
+		}
+		groupChunk.lock.Lock()
+		defer groupChunk.lock.Unlock()
+		var flows []*ofp.OfpFlowStats
+		if flows, err = agent.deleteFlowsOfGroup(ctx, groupID); err != nil {
+			logger.Errorw("cannot-update-flow-for-group-delete", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "groupID": groupID})
+			return err
+		}
+		//remove from store
+		if err := agent.removeLogicalDeviceFlowGroup(ctx, groupID); err != nil {
+			return err
+		}
+		affectedFlows = append(affectedFlows, flows...)
+		affectedGroups = append(affectedGroups, groupChunk.group)
+		groupsChanged = true
+
+	}
+
+	if err != nil || groupsChanged {
+		var deviceRules *fu.DeviceRules
+		deviceRules, err = agent.flowDecomposer.DecomposeRules(ctx, agent, ofp.Flows{Items: affectedFlows}, ofp.FlowGroups{Items: affectedGroups})
+		if err != nil {
+			return err
+		}
+		logger.Debugw("rules", log.Fields{"rules": deviceRules.String()})
+
+		// Update the devices
+		respChnls := agent.updateFlowsAndGroupsOfDevice(ctx, deviceRules, nil)
+
+		// Wait for completion
+		go func() {
+			if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
+				logger.Warnw("failure-updating-device-flows-groups", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
+				//TODO: Revert flow changes
+			}
+		}()
+	}
+	return nil
+}
+
+func (agent *LogicalAgent) groupModify(ctx context.Context, groupMod *ofp.OfpGroupMod) error {
+	logger.Debug("groupModify")
+	if groupMod == nil {
+		return nil
+	}
+
+	groupID := groupMod.GroupId
+	agent.groupLock.RLock()
+	groupChunk, ok := agent.groups[groupID]
+	agent.groupLock.RUnlock()
+	if !ok {
+		return fmt.Errorf("group-absent:%d", groupID)
+	}
+	//Don't let any other thread to make modifications to this group till all done here.
+	groupChunk.lock.Lock()
+	defer groupChunk.lock.Unlock()
+	//replace existing group entry with new group definition
+	groupEntry := fu.GroupEntryFromGroupMod(groupMod)
+	deviceRules := fu.NewDeviceRules()
+	deviceRules.CreateEntryIfNotExist(agent.rootDeviceID)
+	fg := fu.NewFlowsAndGroups()
+	fg.AddGroup(fu.GroupEntryFromGroupMod(groupMod))
+	deviceRules.AddFlowsAndGroup(agent.rootDeviceID, fg)
+
+	logger.Debugw("rules", log.Fields{"rules-for-group-modify": deviceRules.String()})
+	//update KV
+	if err := agent.updateLogicalDeviceFlowGroup(ctx, groupEntry, groupChunk); err != nil {
+		logger.Errorw("Cannot-update-logical-group", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
+		return err
+	}
+
+	// Update the devices
+	respChnls := agent.updateFlowsAndGroupsOfDevice(ctx, deviceRules, &voltha.FlowMetadata{})
+
+	// Wait for completion
+	go func() {
+		if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, respChnls...); res != nil {
+			logger.Warnw("failure-updating-device-flows-groups", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "errors": res})
+			//TODO: Revert flow changes
+		}
+	}()
+	return nil
+}
diff --git a/rw_core/core/device/logical_agent_group_loader.go b/rw_core/core/device/logical_agent_group_loader.go
new file mode 100644
index 0000000..53e4076
--- /dev/null
+++ b/rw_core/core/device/logical_agent_group_loader.go
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package device
+
+import (
+	"context"
+	"fmt"
+	"sync"
+
+	"github.com/gogo/protobuf/proto"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+)
+
+//GroupChunk keeps a group entry and its lock. The lock in the struct is used to syncronize the
+//modifications for the related group.
+type GroupChunk struct {
+	group *ofp.OfpGroupEntry
+	lock  sync.Mutex
+}
+
+func (agent *LogicalAgent) loadGroups(ctx context.Context) {
+	agent.groupLock.Lock()
+	defer agent.groupLock.Unlock()
+
+	var groups []*ofp.OfpGroupEntry
+	if err := agent.clusterDataProxy.List(ctx, "groups/"+agent.logicalDeviceID, &groups); err != nil {
+		logger.Errorw("Failed-to-list-groups-from-proxy", log.Fields{"error": err})
+		return
+	}
+	for _, group := range groups {
+		if group.Desc != nil {
+			groupChunk := GroupChunk{
+				group: group,
+			}
+			agent.groups[group.Desc.GroupId] = &groupChunk
+		}
+	}
+	logger.Infow("Groups-are-loaded-into-the-cache-from-store", log.Fields{"logicalDeviceID": agent.logicalDeviceID})
+}
+
+//updateLogicalDeviceFlowGroup updates the flow groups in store and cache
+//It is assumed that the chunk lock has been acquired before this function is called
+func (agent *LogicalAgent) updateLogicalDeviceFlowGroup(ctx context.Context, groupEntry *ofp.OfpGroupEntry, groupChunk *GroupChunk) error {
+	path := fmt.Sprintf("groups/%s/%d", agent.logicalDeviceID, groupEntry.Desc.GroupId)
+	if err := agent.clusterDataProxy.Update(ctx, path, groupEntry); err != nil {
+		logger.Errorw("error-updating-logical-device-with-group", log.Fields{"error": err})
+		return err
+	}
+	groupChunk.group = groupEntry
+	return nil
+}
+
+//removeLogicalDeviceFlowGroup removes the flow groups in store and cache
+//It is assumed that the chunk lock has been acquired before this function is called
+func (agent *LogicalAgent) removeLogicalDeviceFlowGroup(ctx context.Context, groupID uint32) error {
+	path := fmt.Sprintf("groups/%s/%d", agent.logicalDeviceID, groupID)
+	if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
+		return fmt.Errorf("couldnt-delete-group-from-store-%s", path)
+	}
+	agent.groupLock.Lock()
+	defer agent.groupLock.Unlock()
+	delete(agent.groups, groupID)
+	return nil
+}
+
+// ListLogicalDeviceFlowGroups returns logical device flow groups
+func (agent *LogicalAgent) ListLogicalDeviceFlowGroups(ctx context.Context) (*ofp.FlowGroups, error) {
+	logger.Debug("ListLogicalDeviceFlowGroups")
+
+	var groupEntries []*ofp.OfpGroupEntry
+	agent.groupLock.RLock()
+	defer agent.groupLock.RUnlock()
+	for _, value := range agent.groups {
+		groupEntries = append(groupEntries, (proto.Clone(value.group)).(*ofp.OfpGroupEntry))
+	}
+	return &ofp.FlowGroups{Items: groupEntries}, nil
+}
diff --git a/rw_core/core/device/logical_agent_meter.go b/rw_core/core/device/logical_agent_meter.go
new file mode 100644
index 0000000..c211f1e
--- /dev/null
+++ b/rw_core/core/device/logical_agent_meter.go
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package device
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+
+	fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+// updateMeterTable updates the meter table of that logical device
+func (agent *LogicalAgent) updateMeterTable(ctx context.Context, meterMod *ofp.OfpMeterMod) error {
+	logger.Debug("updateMeterTable")
+	if meterMod == nil {
+		return nil
+	}
+	switch meterMod.GetCommand() {
+	case ofp.OfpMeterModCommand_OFPMC_ADD:
+		return agent.meterAdd(ctx, meterMod)
+	case ofp.OfpMeterModCommand_OFPMC_DELETE:
+		return agent.meterDelete(ctx, meterMod)
+	case ofp.OfpMeterModCommand_OFPMC_MODIFY:
+		return agent.meterModify(ctx, meterMod)
+	}
+	return status.Errorf(codes.Internal,
+		"unhandled-command: lDeviceId:%s, command:%s", agent.logicalDeviceID, meterMod.GetCommand())
+}
+
+func (agent *LogicalAgent) meterAdd(ctx context.Context, meterMod *ofp.OfpMeterMod) error {
+	logger.Debugw("meterAdd", log.Fields{"metermod": *meterMod})
+	if meterMod == nil {
+		return nil
+	}
+
+	meterEntry := fu.MeterEntryFromMeterMod(meterMod)
+	agent.meterLock.Lock()
+	//check if the meter already exists or not
+	_, ok := agent.meters[meterMod.MeterId]
+	if ok {
+		logger.Infow("Meter-already-exists", log.Fields{"meter": *meterMod})
+		agent.meterLock.Unlock()
+		return nil
+	}
+
+	mChunk := MeterChunk{
+		meter: meterEntry,
+	}
+	//Add to map and acquire the per meter lock
+	agent.meters[meterMod.MeterId] = &mChunk
+	mChunk.lock.Lock()
+	defer mChunk.lock.Unlock()
+	agent.meterLock.Unlock()
+	meterID := strconv.Itoa(int(meterMod.MeterId))
+	if err := agent.clusterDataProxy.AddWithID(ctx, "meters/"+agent.logicalDeviceID, meterID, meterEntry); err != nil {
+		logger.Errorw("failed-adding-meter", log.Fields{"deviceID": agent.logicalDeviceID, "meterID": meterID, "err": err})
+		//Revert the map
+		agent.meterLock.Lock()
+		delete(agent.meters, meterMod.MeterId)
+		agent.meterLock.Unlock()
+		return err
+	}
+
+	logger.Debugw("Meter-added-successfully", log.Fields{"Added-meter": meterEntry})
+	return nil
+}
+
+func (agent *LogicalAgent) meterDelete(ctx context.Context, meterMod *ofp.OfpMeterMod) error {
+	logger.Debug("meterDelete", log.Fields{"meterMod": *meterMod})
+	if meterMod == nil {
+		return nil
+	}
+	agent.meterLock.RLock()
+	meterChunk, ok := agent.meters[meterMod.MeterId]
+	agent.meterLock.RUnlock()
+	if ok {
+		//Dont let anyone to do any changes to this meter until this is done.
+		//And wait if someone else is already making modifications. Do this with per meter lock.
+		meterChunk.lock.Lock()
+		defer meterChunk.lock.Unlock()
+		if err := agent.deleteFlowsOfMeter(ctx, meterMod.MeterId); err != nil {
+			return err
+		}
+		//remove from the store and cache
+		if err := agent.removeLogicalDeviceMeter(ctx, meterMod.MeterId); err != nil {
+			return err
+		}
+		logger.Debugw("meterDelete-success", log.Fields{"meterID": meterMod.MeterId})
+	} else {
+		logger.Warnw("meter-not-found", log.Fields{"meterID": meterMod.MeterId})
+	}
+	return nil
+}
+
+func (agent *LogicalAgent) meterModify(ctx context.Context, meterMod *ofp.OfpMeterMod) error {
+	logger.Debug("meterModify")
+	if meterMod == nil {
+		return nil
+	}
+	newMeter := fu.MeterEntryFromMeterMod(meterMod)
+	agent.meterLock.RLock()
+	meterChunk, ok := agent.meters[newMeter.Config.MeterId]
+	agent.meterLock.RUnlock()
+	if !ok {
+		return fmt.Errorf("no-meter-to-modify:%d", newMeter.Config.MeterId)
+	}
+	//Release the map lock and syncronize per meter
+	meterChunk.lock.Lock()
+	defer meterChunk.lock.Unlock()
+	oldMeter := meterChunk.meter
+	newMeter.Stats.FlowCount = oldMeter.Stats.FlowCount
+
+	if err := agent.updateLogicalDeviceMeter(ctx, newMeter, meterChunk); err != nil {
+		logger.Errorw("db-meter-update-failed", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "meterID": newMeter.Config.MeterId})
+		return err
+	}
+	logger.Debugw("replaced-with-new-meter", log.Fields{"oldMeter": oldMeter, "newMeter": newMeter})
+	return nil
+}
diff --git a/rw_core/core/device/logical_agent_meter_loader.go b/rw_core/core/device/logical_agent_meter_loader.go
new file mode 100644
index 0000000..4408bf1
--- /dev/null
+++ b/rw_core/core/device/logical_agent_meter_loader.go
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package device
+
+import (
+	"context"
+	"fmt"
+	"sync"
+
+	"github.com/gogo/protobuf/proto"
+	fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+)
+
+//MeterChunk keeps a meter entry and its lock. The lock in the struct is used to syncronize the
+//modifications for the related meter.
+type MeterChunk struct {
+	meter *ofp.OfpMeterEntry
+	lock  sync.Mutex
+}
+
+func (agent *LogicalAgent) loadMeters(ctx context.Context) {
+	agent.meterLock.Lock()
+	defer agent.meterLock.Unlock()
+
+	var meters []*ofp.OfpMeterEntry
+	if err := agent.clusterDataProxy.List(ctx, "meters/"+agent.logicalDeviceID, &meters); err != nil {
+		logger.Errorw("Failed-to-list-meters-from-proxy", log.Fields{"error": err})
+		return
+	}
+	for _, meter := range meters {
+		if meter.Config != nil {
+			meterChunk := MeterChunk{
+				meter: meter,
+			}
+			agent.meters[meter.Config.MeterId] = &meterChunk
+		}
+	}
+}
+
+//updateLogicalDeviceMeter updates meter info in store and cache
+//It is assumed that the chunk lock has been acquired before this function is called
+func (agent *LogicalAgent) updateLogicalDeviceMeter(ctx context.Context, meter *ofp.OfpMeterEntry, meterChunk *MeterChunk) error {
+	path := fmt.Sprintf("meters/%s/%d", agent.logicalDeviceID, meter.Config.MeterId)
+	if err := agent.clusterDataProxy.Update(ctx, path, meter); err != nil {
+		logger.Errorw("error-updating-logical-device-with-meters", log.Fields{"error": err})
+		return err
+	}
+	meterChunk.meter = meter
+	return nil
+}
+
+//removeLogicalDeviceMeter deletes the meter from store and cache
+//It is assumed that the chunk lock has been acquired before this function is called
+func (agent *LogicalAgent) removeLogicalDeviceMeter(ctx context.Context, meterID uint32) error {
+	path := fmt.Sprintf("meters/%s/%d", agent.logicalDeviceID, meterID)
+	if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
+		return fmt.Errorf("couldnt-delete-meter-from-store-%s", path)
+	}
+	agent.meterLock.Lock()
+	defer agent.meterLock.Unlock()
+	delete(agent.meters, meterID)
+	return nil
+}
+
+// ListLogicalDeviceMeters returns logical device meters
+func (agent *LogicalAgent) ListLogicalDeviceMeters(ctx context.Context) (*ofp.Meters, error) {
+	logger.Debug("ListLogicalDeviceMeters")
+
+	var meterEntries []*ofp.OfpMeterEntry
+	agent.meterLock.RLock()
+	defer agent.meterLock.RUnlock()
+	for _, meterChunk := range agent.meters {
+		meterEntries = append(meterEntries, (proto.Clone(meterChunk.meter)).(*ofp.OfpMeterEntry))
+	}
+	return &ofp.Meters{Items: meterEntries}, nil
+}
+
+// GetMeterConfig returns meter config
+func (agent *LogicalAgent) GetMeterConfig(flows []*ofp.OfpFlowStats, meters []*ofp.OfpMeterEntry, metadata *voltha.FlowMetadata) error {
+	m := make(map[uint32]bool)
+	for _, flow := range flows {
+		if flowMeterID := fu.GetMeterIdFromFlow(flow); flowMeterID != 0 && !m[flowMeterID] {
+			foundMeter := false
+			// Meter is present in the flow , Get from logical device
+			for _, meter := range meters {
+				if flowMeterID == meter.Config.MeterId {
+					metadata.Meters = append(metadata.Meters, meter.Config)
+					logger.Debugw("Found meter in logical device",
+						log.Fields{"meterID": flowMeterID, "meter-band": meter.Config})
+					m[flowMeterID] = true
+					foundMeter = true
+					break
+				}
+			}
+			if !foundMeter {
+				logger.Errorw("Meter-referred-by-flow-is-not-found-in-logicaldevice",
+					log.Fields{"meterID": flowMeterID, "Available-meters": meters, "flow": *flow})
+				return fmt.Errorf("Meter-referred-by-flow-is-not-found-in-logicaldevice.MeterId-%d", flowMeterID)
+			}
+		}
+	}
+	logger.Debugw("meter-bands-for-flows", log.Fields{"flows": len(flows), "metadata": metadata})
+	return nil
+}
+
+func (agent *LogicalAgent) updateFlowCountOfMeterStats(ctx context.Context, modCommand *ofp.OfpFlowMod, flow *ofp.OfpFlowStats, revertUpdate bool) bool {
+	flowCommand := modCommand.GetCommand()
+	meterID := fu.GetMeterIdFromFlow(flow)
+	logger.Debugw("Meter-id-in-flow-mod", log.Fields{"meterId": meterID})
+	if meterID == 0 {
+		logger.Debugw("No-meter-present-in-the-flow", log.Fields{"flow": *flow})
+		return true
+	}
+
+	if flowCommand != ofp.OfpFlowModCommand_OFPFC_ADD && flowCommand != ofp.OfpFlowModCommand_OFPFC_DELETE_STRICT {
+		return true
+	}
+	agent.meterLock.RLock()
+	meterChunk, ok := agent.meters[meterID]
+	agent.meterLock.RUnlock()
+	if !ok {
+		logger.Debugw("Meter-is-not-present-in-logical-device", log.Fields{"meterID": meterID})
+		return true
+	}
+
+	//acquire the meter lock
+	meterChunk.lock.Lock()
+	defer meterChunk.lock.Unlock()
+
+	if flowCommand == ofp.OfpFlowModCommand_OFPFC_ADD {
+		if revertUpdate {
+			meterChunk.meter.Stats.FlowCount--
+		} else {
+			meterChunk.meter.Stats.FlowCount++
+		}
+	} else if flowCommand == ofp.OfpFlowModCommand_OFPFC_DELETE_STRICT {
+		if revertUpdate {
+			meterChunk.meter.Stats.FlowCount++
+		} else {
+			meterChunk.meter.Stats.FlowCount--
+		}
+	}
+
+	//	Update store and cache
+	if err := agent.updateLogicalDeviceMeter(ctx, meterChunk.meter, meterChunk); err != nil {
+		logger.Debugw("unable-to-update-meter-in-db", log.Fields{"logicalDevice": agent.logicalDeviceID, "meterID": meterID})
+		return false
+	}
+
+	logger.Debugw("updated-meter-flow-stats", log.Fields{"meterId": meterID})
+	return true
+}
diff --git a/rw_core/core/device/logical_agent_port.go b/rw_core/core/device/logical_agent_port.go
new file mode 100644
index 0000000..27ce04b
--- /dev/null
+++ b/rw_core/core/device/logical_agent_port.go
@@ -0,0 +1,650 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package device
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/gogo/protobuf/proto"
+	coreutils "github.com/opencord/voltha-go/rw_core/utils"
+	fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ic "github.com/opencord/voltha-protos/v3/go/inter_container"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+// ListLogicalDevicePorts returns logical device ports
+func (agent *LogicalAgent) ListLogicalDevicePorts(ctx context.Context) (*voltha.LogicalPorts, error) {
+	logger.Debug("ListLogicalDevicePorts")
+	logicalDevice, err := agent.GetLogicalDevice(ctx)
+	if err != nil {
+		return nil, err
+	}
+	if logicalDevice == nil {
+		return &voltha.LogicalPorts{}, nil
+	}
+	lPorts := make([]*voltha.LogicalPort, 0)
+	lPorts = append(lPorts, logicalDevice.Ports...)
+	return &voltha.LogicalPorts{Items: lPorts}, nil
+}
+
+func (agent *LogicalAgent) updateLogicalPort(ctx context.Context, device *voltha.Device, port *voltha.Port) error {
+	logger.Debugw("updateLogicalPort", log.Fields{"deviceId": device.Id, "port": port})
+	var err error
+	if port.Type == voltha.Port_ETHERNET_NNI {
+		if _, err = agent.addNNILogicalPort(ctx, device, port); err != nil {
+			return err
+		}
+		agent.addLogicalPortToMap(port.PortNo, true)
+	} else if port.Type == voltha.Port_ETHERNET_UNI {
+		if _, err = agent.addUNILogicalPort(ctx, device, port); err != nil {
+			return err
+		}
+		agent.addLogicalPortToMap(port.PortNo, false)
+	} else {
+		// Update the device routes to ensure all routes on the logical device have been calculated
+		if err = agent.buildRoutes(ctx); err != nil {
+			// Not an error - temporary state
+			logger.Warnw("failed-to-update-routes", log.Fields{"device-id": device.Id, "port": port, "error": err})
+		}
+	}
+	return nil
+}
+
+// setupLogicalPorts is invoked once the logical device has been created and is ready to get ports
+// added to it.  While the logical device was being created we could have received requests to add
+// NNI and UNI ports which were discarded.  Now is the time to add them if needed
+func (agent *LogicalAgent) setupLogicalPorts(ctx context.Context) error {
+	logger.Infow("setupLogicalPorts", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
+	// First add any NNI ports which could have been missing
+	if err := agent.setupNNILogicalPorts(ctx, agent.rootDeviceID); err != nil {
+		logger.Errorw("error-setting-up-NNI-ports", log.Fields{"error": err, "deviceId": agent.rootDeviceID})
+		return err
+	}
+
+	// Now, set up the UNI ports if needed.
+	children, err := agent.deviceMgr.GetAllChildDevices(ctx, agent.rootDeviceID)
+	if err != nil {
+		logger.Errorw("error-getting-child-devices", log.Fields{"error": err, "deviceId": agent.rootDeviceID})
+		return err
+	}
+	responses := make([]coreutils.Response, 0)
+	for _, child := range children.Items {
+		response := coreutils.NewResponse()
+		responses = append(responses, response)
+		go func(child *voltha.Device) {
+			if err = agent.setupUNILogicalPorts(context.Background(), child); err != nil {
+				logger.Error("setting-up-UNI-ports-failed", log.Fields{"deviceID": child.Id})
+				response.Error(status.Errorf(codes.Internal, "UNI-ports-setup-failed: %s", child.Id))
+			}
+			response.Done()
+		}(child)
+	}
+	// Wait for completion
+	if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, responses...); res != nil {
+		return status.Errorf(codes.Aborted, "errors-%s", res)
+	}
+	return nil
+}
+
+// setupNNILogicalPorts creates an NNI port on the logical device that represents an NNI interface on a root device
+func (agent *LogicalAgent) setupNNILogicalPorts(ctx context.Context, deviceID string) error {
+	logger.Infow("setupNNILogicalPorts-start", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
+	// Build the logical device based on information retrieved from the device adapter
+	var err error
+
+	var device *voltha.Device
+	if device, err = agent.deviceMgr.getDevice(ctx, deviceID); err != nil {
+		logger.Errorw("error-retrieving-device", log.Fields{"error": err, "deviceId": deviceID})
+		return err
+	}
+
+	//Get UNI port number
+	for _, port := range device.Ports {
+		if port.Type == voltha.Port_ETHERNET_NNI {
+			if _, err = agent.addNNILogicalPort(ctx, device, port); err != nil {
+				logger.Errorw("error-adding-UNI-port", log.Fields{"error": err})
+			}
+			agent.addLogicalPortToMap(port.PortNo, true)
+		}
+	}
+	return err
+}
+
+// updatePortState updates the port state of the device
+func (agent *LogicalAgent) updatePortState(ctx context.Context, deviceID string, portNo uint32, operStatus voltha.OperStatus_Types) error {
+	logger.Infow("updatePortState-start", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "portNo": portNo, "state": operStatus})
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return err
+	}
+	defer agent.requestQueue.RequestComplete()
+	// Get the latest logical device info
+	original := agent.getLogicalDeviceWithoutLock()
+	updatedPorts := clonePorts(original.Ports)
+	for _, port := range updatedPorts {
+		if port.DeviceId == deviceID && port.DevicePortNo == portNo {
+			if operStatus == voltha.OperStatus_ACTIVE {
+				port.OfpPort.Config = port.OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
+			} else {
+				port.OfpPort.Config = port.OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
+			}
+			// Update the logical device
+			if err := agent.updateLogicalDevicePortsWithoutLock(ctx, original, updatedPorts); err != nil {
+				logger.Errorw("error-updating-logical-device", log.Fields{"error": err})
+				return err
+			}
+			return nil
+		}
+	}
+	return status.Errorf(codes.NotFound, "port-%d-not-exist", portNo)
+}
+
+// updatePortsState updates the ports state related to the device
+func (agent *LogicalAgent) updatePortsState(ctx context.Context, device *voltha.Device, state voltha.OperStatus_Types) error {
+	logger.Infow("updatePortsState-start", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return err
+	}
+	defer agent.requestQueue.RequestComplete()
+	// Get the latest logical device info
+	original := agent.getLogicalDeviceWithoutLock()
+	updatedPorts := clonePorts(original.Ports)
+	for _, port := range updatedPorts {
+		if port.DeviceId == device.Id {
+			if state == voltha.OperStatus_ACTIVE {
+				port.OfpPort.Config = port.OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
+			} else {
+				port.OfpPort.Config = port.OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
+			}
+		}
+	}
+	// Updating the logical device will trigger the poprt change events to be populated to the controller
+	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, original, updatedPorts); err != nil {
+		logger.Warnw("logical-device-update-failed", log.Fields{"ldeviceId": agent.logicalDeviceID, "error": err})
+		return err
+	}
+	return nil
+}
+
+// setupUNILogicalPorts creates a UNI port on the logical device that represents a child UNI interface
+func (agent *LogicalAgent) setupUNILogicalPorts(ctx context.Context, childDevice *voltha.Device) error {
+	logger.Infow("setupUNILogicalPort", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
+	// Build the logical device based on information retrieved from the device adapter
+	var err error
+	var added bool
+	//Get UNI port number
+	for _, port := range childDevice.Ports {
+		if port.Type == voltha.Port_ETHERNET_UNI {
+			if added, err = agent.addUNILogicalPort(ctx, childDevice, port); err != nil {
+				logger.Errorw("error-adding-UNI-port", log.Fields{"error": err})
+			}
+			if added {
+				agent.addLogicalPortToMap(port.PortNo, false)
+			}
+		}
+	}
+	return err
+}
+
+// deleteAllLogicalPorts deletes all logical ports associated with this logical device
+func (agent *LogicalAgent) deleteAllLogicalPorts(ctx context.Context) error {
+	logger.Infow("updatePortsState-start", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return err
+	}
+	defer agent.requestQueue.RequestComplete()
+	// Get the latest logical device info
+	cloned := agent.getLogicalDeviceWithoutLock()
+
+	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, cloned, []*voltha.LogicalPort{}); err != nil {
+		logger.Warnw("logical-device-update-failed", log.Fields{"ldeviceId": agent.logicalDeviceID, "error": err})
+		return err
+	}
+	return nil
+}
+
+// deleteLogicalPort removes the logical port
+func (agent *LogicalAgent) deleteLogicalPort(ctx context.Context, lPort *voltha.LogicalPort) error {
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return err
+	}
+	defer agent.requestQueue.RequestComplete()
+
+	logicalDevice := agent.getLogicalDeviceWithoutLock()
+
+	index := -1
+	for i, logicalPort := range logicalDevice.Ports {
+		if logicalPort.Id == lPort.Id {
+			index = i
+			break
+		}
+	}
+	if index >= 0 {
+		clonedPorts := clonePorts(logicalDevice.Ports)
+		if index < len(clonedPorts)-1 {
+			copy(clonedPorts[index:], clonedPorts[index+1:])
+		}
+		clonedPorts[len(clonedPorts)-1] = nil
+		clonedPorts = clonedPorts[:len(clonedPorts)-1]
+		logger.Debugw("logical-port-deleted", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
+		if err := agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, clonedPorts); err != nil {
+			logger.Errorw("logical-device-update-failed", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
+			return err
+		}
+
+		// Remove the logical port from cache
+		agent.deleteLogicalPortsFromMap([]uint32{lPort.DevicePortNo})
+		// Reset the logical device routes
+		go func() {
+			if err := agent.buildRoutes(context.Background()); err != nil {
+				logger.Warnw("device-routes-not-ready", log.Fields{"logicalDeviceId": agent.logicalDeviceID, "error": err})
+			}
+		}()
+	}
+	return nil
+}
+
+// deleteLogicalPorts removes the logical ports associated with that deviceId
+func (agent *LogicalAgent) deleteLogicalPorts(ctx context.Context, deviceID string) error {
+	logger.Debugw("deleting-logical-ports", log.Fields{"device-id": deviceID})
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return err
+	}
+	defer agent.requestQueue.RequestComplete()
+
+	logicalDevice := agent.getLogicalDeviceWithoutLock()
+	lPortstoKeep := []*voltha.LogicalPort{}
+	lPortsNoToDelete := []uint32{}
+	for _, logicalPort := range logicalDevice.Ports {
+		if logicalPort.DeviceId != deviceID {
+			lPortstoKeep = append(lPortstoKeep, logicalPort)
+		} else {
+			lPortsNoToDelete = append(lPortsNoToDelete, logicalPort.DevicePortNo)
+		}
+	}
+	logger.Debugw("deleted-logical-ports", log.Fields{"ports": lPortstoKeep})
+	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, lPortstoKeep); err != nil {
+		logger.Errorw("logical-device-update-failed", log.Fields{"logical-device-id": agent.logicalDeviceID})
+		return err
+	}
+	// Remove the port from the cached logical ports set
+	agent.deleteLogicalPortsFromMap(lPortsNoToDelete)
+
+	// Reset the logical device routes
+	go func() {
+		if err := agent.buildRoutes(context.Background()); err != nil {
+			logger.Warnw("routes-not-ready", log.Fields{"logical-device-id": agent.logicalDeviceID, "error": err})
+		}
+	}()
+
+	return nil
+}
+
+// enableLogicalPort enables the logical port
+func (agent *LogicalAgent) enableLogicalPort(ctx context.Context, lPortID string) error {
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return err
+	}
+	defer agent.requestQueue.RequestComplete()
+
+	logicalDevice := agent.getLogicalDeviceWithoutLock()
+
+	index := -1
+	for i, logicalPort := range logicalDevice.Ports {
+		if logicalPort.Id == lPortID {
+			index = i
+			break
+		}
+	}
+	if index >= 0 {
+		clonedPorts := clonePorts(logicalDevice.Ports)
+		clonedPorts[index].OfpPort.Config = clonedPorts[index].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+		return agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, clonedPorts)
+	}
+	return status.Errorf(codes.NotFound, "Port %s on Logical Device %s", lPortID, agent.logicalDeviceID)
+}
+
+// disableLogicalPort disabled the logical port
+func (agent *LogicalAgent) disableLogicalPort(ctx context.Context, lPortID string) error {
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return err
+	}
+	defer agent.requestQueue.RequestComplete()
+
+	// Get the most up to date logical device
+	logicalDevice := agent.getLogicalDeviceWithoutLock()
+	index := -1
+	for i, logicalPort := range logicalDevice.Ports {
+		if logicalPort.Id == lPortID {
+			index = i
+			break
+		}
+	}
+	if index >= 0 {
+		clonedPorts := clonePorts(logicalDevice.Ports)
+		clonedPorts[index].OfpPort.Config = (clonedPorts[index].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)) | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+		return agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, clonedPorts)
+	}
+	return status.Errorf(codes.NotFound, "Port %s on Logical Device %s", lPortID, agent.logicalDeviceID)
+}
+
+// addNNILogicalPort adds an NNI port to the logical device.  It returns a bool representing whether a port has been
+// added and an eror in case a valid error is encountered. If the port was successfully added it will return
+// (true, nil).   If the device is not in the correct state it will return (false, nil) as this is a valid
+// scenario. This also applies to the case where the port was already added.
+func (agent *LogicalAgent) addNNILogicalPort(ctx context.Context, device *voltha.Device, port *voltha.Port) (bool, error) {
+	logger.Debugw("addNNILogicalPort", log.Fields{"NNI": port})
+
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return false, err
+	}
+	if agent.portExist(device, port) {
+		logger.Debugw("port-already-exist", log.Fields{"port": port})
+		agent.requestQueue.RequestComplete()
+		return false, nil
+	}
+	agent.requestQueue.RequestComplete()
+
+	var portCap *ic.PortCapability
+	var err error
+	// First get the port capability
+	if portCap, err = agent.deviceMgr.getPortCapability(ctx, device.Id, port.PortNo); err != nil {
+		logger.Errorw("error-retrieving-port-capabilities", log.Fields{"error": err})
+		return false, err
+	}
+
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return false, err
+	}
+
+	defer agent.requestQueue.RequestComplete()
+	// Double check again if this port has been already added since the getPortCapability could have taken a long time
+	if agent.portExist(device, port) {
+		logger.Debugw("port-already-exist", log.Fields{"port": port})
+		return false, nil
+	}
+
+	portCap.Port.RootPort = true
+	lp := (proto.Clone(portCap.Port)).(*voltha.LogicalPort)
+	lp.DeviceId = device.Id
+	lp.Id = fmt.Sprintf("nni-%d", port.PortNo)
+	lp.OfpPort.PortNo = port.PortNo
+	lp.OfpPort.Name = lp.Id
+	lp.DevicePortNo = port.PortNo
+
+	ld := agent.getLogicalDeviceWithoutLock()
+
+	clonedPorts := clonePorts(ld.Ports)
+	if clonedPorts == nil {
+		clonedPorts = make([]*voltha.LogicalPort, 0)
+	}
+	clonedPorts = append(clonedPorts, lp)
+
+	if err = agent.updateLogicalDevicePortsWithoutLock(ctx, ld, clonedPorts); err != nil {
+		logger.Errorw("error-updating-logical-device", log.Fields{"error": err})
+		return false, err
+	}
+
+	// Update the device routes with this new logical port
+	clonedLP := (proto.Clone(lp)).(*voltha.LogicalPort)
+	go func() {
+		if err := agent.updateRoutes(context.Background(), clonedLP); err != nil {
+			logger.Warnw("routes-not-ready", log.Fields{"logical-device-id": agent.logicalDeviceID, "logical-port": lp.OfpPort.PortNo, "error": err})
+		}
+	}()
+
+	return true, nil
+}
+
+func (agent *LogicalAgent) portExist(device *voltha.Device, port *voltha.Port) bool {
+	ldevice := agent.getLogicalDeviceWithoutLock()
+	for _, lPort := range ldevice.Ports {
+		if lPort.DeviceId == device.Id && lPort.DevicePortNo == port.PortNo && lPort.Id == port.Label {
+			return true
+		}
+	}
+	return false
+}
+
+// addUNILogicalPort adds an UNI port to the logical device.  It returns a bool representing whether a port has been
+// added and an eror in case a valid error is encountered. If the port was successfully added it will return
+// (true, nil).   If the device is not in the correct state it will return (false, nil) as this is a valid
+// scenario. This also applies to the case where the port was already added.
+func (agent *LogicalAgent) addUNILogicalPort(ctx context.Context, childDevice *voltha.Device, port *voltha.Port) (bool, error) {
+	logger.Debugw("addUNILogicalPort", log.Fields{"port": port})
+	if childDevice.AdminState != voltha.AdminState_ENABLED || childDevice.OperStatus != voltha.OperStatus_ACTIVE {
+		logger.Infow("device-not-ready", log.Fields{"deviceId": childDevice.Id, "admin": childDevice.AdminState, "oper": childDevice.OperStatus})
+		return false, nil
+	}
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return false, err
+	}
+
+	if agent.portExist(childDevice, port) {
+		logger.Debugw("port-already-exist", log.Fields{"port": port})
+		agent.requestQueue.RequestComplete()
+		return false, nil
+	}
+	agent.requestQueue.RequestComplete()
+	var portCap *ic.PortCapability
+	var err error
+	// First get the port capability
+	if portCap, err = agent.deviceMgr.getPortCapability(ctx, childDevice.Id, port.PortNo); err != nil {
+		logger.Errorw("error-retrieving-port-capabilities", log.Fields{"error": err})
+		return false, err
+	}
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return false, err
+	}
+	defer agent.requestQueue.RequestComplete()
+	// Double check again if this port has been already added since the getPortCapability could have taken a long time
+	if agent.portExist(childDevice, port) {
+		logger.Debugw("port-already-exist", log.Fields{"port": port})
+		return false, nil
+	}
+	// Get stored logical device
+	ldevice := agent.getLogicalDeviceWithoutLock()
+
+	logger.Debugw("adding-uni", log.Fields{"deviceId": childDevice.Id})
+	portCap.Port.RootPort = false
+	portCap.Port.Id = port.Label
+	portCap.Port.OfpPort.PortNo = port.PortNo
+	portCap.Port.DeviceId = childDevice.Id
+	portCap.Port.DevicePortNo = port.PortNo
+	clonedPorts := clonePorts(ldevice.Ports)
+	if clonedPorts == nil {
+		clonedPorts = make([]*voltha.LogicalPort, 0)
+	}
+	clonedPorts = append(clonedPorts, portCap.Port)
+	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, ldevice, clonedPorts); err != nil {
+		return false, err
+	}
+	// Update the device graph with this new logical port
+	clonedLP := (proto.Clone(portCap.Port)).(*voltha.LogicalPort)
+
+	go func() {
+		if err := agent.updateRoutes(context.Background(), clonedLP); err != nil {
+			logger.Warn("routes-not-ready", log.Fields{"logical-device-id": agent.logicalDeviceID, "error": err})
+		}
+	}()
+
+	return true, nil
+}
+
+func clonePorts(ports []*voltha.LogicalPort) []*voltha.LogicalPort {
+	return proto.Clone(&voltha.LogicalPorts{Items: ports}).(*voltha.LogicalPorts).Items
+}
+
+//updateLogicalDevicePortsWithoutLock updates the
+func (agent *LogicalAgent) updateLogicalDevicePortsWithoutLock(ctx context.Context, device *voltha.LogicalDevice, newPorts []*voltha.LogicalPort) error {
+	oldPorts := device.Ports
+	device.Ports = newPorts
+	if err := agent.updateLogicalDeviceWithoutLock(ctx, device); err != nil {
+		return err
+	}
+	agent.portUpdated(oldPorts, newPorts)
+	return nil
+}
+
+// diff go over two lists of logical ports and return what's new, what's changed and what's removed.
+func diff(oldList, newList []*voltha.LogicalPort) (newPorts, changedPorts, deletedPorts map[string]*voltha.LogicalPort) {
+	newPorts = make(map[string]*voltha.LogicalPort, len(newList))
+	changedPorts = make(map[string]*voltha.LogicalPort, len(oldList))
+	deletedPorts = make(map[string]*voltha.LogicalPort, len(oldList))
+
+	for _, n := range newList {
+		newPorts[n.Id] = n
+	}
+
+	for _, o := range oldList {
+		if n, have := newPorts[o.Id]; have {
+			delete(newPorts, o.Id) // not new
+			if !proto.Equal(n, o) {
+				changedPorts[n.Id] = n // changed
+			}
+		} else {
+			deletedPorts[o.Id] = o // deleted
+		}
+	}
+
+	return newPorts, changedPorts, deletedPorts
+}
+
+// portUpdated is invoked when a port is updated on the logical device
+func (agent *LogicalAgent) portUpdated(prevPorts, currPorts []*voltha.LogicalPort) interface{} {
+	// Get the difference between the two list
+	newPorts, changedPorts, deletedPorts := diff(prevPorts, currPorts)
+
+	// Send the port change events to the OF controller
+	for _, newP := range newPorts {
+		go agent.ldeviceMgr.SendChangeEvent(agent.logicalDeviceID,
+			&ofp.OfpPortStatus{Reason: ofp.OfpPortReason_OFPPR_ADD, Desc: newP.OfpPort})
+	}
+	for _, change := range changedPorts {
+		go agent.ldeviceMgr.SendChangeEvent(agent.logicalDeviceID,
+			&ofp.OfpPortStatus{Reason: ofp.OfpPortReason_OFPPR_MODIFY, Desc: change.OfpPort})
+	}
+	for _, del := range deletedPorts {
+		go agent.ldeviceMgr.SendChangeEvent(agent.logicalDeviceID,
+			&ofp.OfpPortStatus{Reason: ofp.OfpPortReason_OFPPR_DELETE, Desc: del.OfpPort})
+	}
+
+	return nil
+}
+
+//GetWildcardInputPorts filters out the logical port number from the set of logical ports on the device and
+//returns their port numbers.  This function is invoked only during flow decomposition where the lock on the logical
+//device is already held.  Therefore it is safe to retrieve the logical device without lock.
+func (agent *LogicalAgent) GetWildcardInputPorts(excludePort ...uint32) []uint32 {
+	lPorts := make([]uint32, 0)
+	var exclPort uint32
+	if len(excludePort) == 1 {
+		exclPort = excludePort[0]
+	}
+	lDevice := agent.getLogicalDeviceWithoutLock()
+	for _, port := range lDevice.Ports {
+		if port.OfpPort.PortNo != exclPort {
+			lPorts = append(lPorts, port.OfpPort.PortNo)
+		}
+	}
+	return lPorts
+}
+
+// helpers for agent.logicalPortsNo
+
+func (agent *LogicalAgent) addLogicalPortToMap(portNo uint32, nniPort bool) {
+	agent.lockLogicalPortsNo.Lock()
+	defer agent.lockLogicalPortsNo.Unlock()
+	if exist := agent.logicalPortsNo[portNo]; !exist {
+		agent.logicalPortsNo[portNo] = nniPort
+	}
+}
+
+func (agent *LogicalAgent) addLogicalPortsToMap(lps []*voltha.LogicalPort) {
+	agent.lockLogicalPortsNo.Lock()
+	defer agent.lockLogicalPortsNo.Unlock()
+	for _, lp := range lps {
+		if exist := agent.logicalPortsNo[lp.DevicePortNo]; !exist {
+			agent.logicalPortsNo[lp.DevicePortNo] = lp.RootPort
+		}
+	}
+}
+
+func (agent *LogicalAgent) deleteLogicalPortsFromMap(portsNo []uint32) {
+	agent.lockLogicalPortsNo.Lock()
+	defer agent.lockLogicalPortsNo.Unlock()
+	for _, pNo := range portsNo {
+		delete(agent.logicalPortsNo, pNo)
+	}
+}
+
+func (agent *LogicalAgent) isNNIPort(portNo uint32) bool {
+	agent.lockLogicalPortsNo.RLock()
+	defer agent.lockLogicalPortsNo.RUnlock()
+	if exist := agent.logicalPortsNo[portNo]; exist {
+		return agent.logicalPortsNo[portNo]
+	}
+	return false
+}
+
+func (agent *LogicalAgent) getFirstNNIPort() (uint32, error) {
+	agent.lockLogicalPortsNo.RLock()
+	defer agent.lockLogicalPortsNo.RUnlock()
+	for portNo, nni := range agent.logicalPortsNo {
+		if nni {
+			return portNo, nil
+		}
+	}
+	return 0, status.Error(codes.NotFound, "No NNI port found")
+}
+
+//GetNNIPorts returns NNI ports.
+func (agent *LogicalAgent) GetNNIPorts() []uint32 {
+	agent.lockLogicalPortsNo.RLock()
+	defer agent.lockLogicalPortsNo.RUnlock()
+	nniPorts := make([]uint32, 0)
+	for portNo, nni := range agent.logicalPortsNo {
+		if nni {
+			nniPorts = append(nniPorts, portNo)
+		}
+	}
+	return nniPorts
+}
+
+// getUNILogicalPortNo returns the UNI logical port number specified in the flow
+func (agent *LogicalAgent) getUNILogicalPortNo(flow *ofp.OfpFlowStats) (uint32, error) {
+	var uniPort uint32
+	inPortNo := fu.GetInPort(flow)
+	outPortNo := fu.GetOutPort(flow)
+	if agent.isNNIPort(inPortNo) {
+		uniPort = outPortNo
+	} else if agent.isNNIPort(outPortNo) {
+		uniPort = inPortNo
+	}
+	if uniPort != 0 {
+		return uniPort, nil
+	}
+	return 0, status.Errorf(codes.NotFound, "no-uni-port: %v", flow)
+}
diff --git a/rw_core/core/device/logical_agent_route.go b/rw_core/core/device/logical_agent_route.go
new file mode 100644
index 0000000..6736160
--- /dev/null
+++ b/rw_core/core/device/logical_agent_route.go
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package device
+
+import (
+	"context"
+	"errors"
+	"fmt"
+
+	"github.com/opencord/voltha-go/rw_core/route"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+// GetRoute returns route
+func (agent *LogicalAgent) GetRoute(ctx context.Context, ingressPortNo uint32, egressPortNo uint32) ([]route.Hop, error) {
+	logger.Debugw("getting-route", log.Fields{"ingress-port": ingressPortNo, "egress-port": egressPortNo})
+	routes := make([]route.Hop, 0)
+
+	// Note: A port value of 0 is equivalent to a nil port
+
+	//	Consider different possibilities
+	if egressPortNo != 0 && ((egressPortNo & 0x7fffffff) == uint32(ofp.OfpPortNo_OFPP_CONTROLLER)) {
+		logger.Debugw("controller-flow", log.Fields{"ingressPortNo": ingressPortNo, "egressPortNo": egressPortNo, "logicalPortsNo": agent.logicalPortsNo})
+		if agent.isNNIPort(ingressPortNo) {
+			//This is a trap on the NNI Port
+			if len(agent.deviceRoutes.Routes) == 0 {
+				// If there are no routes set (usually when the logical device has only NNI port(s), then just return an
+				// route with same IngressHop and EgressHop
+				hop := route.Hop{DeviceID: agent.rootDeviceID, Ingress: ingressPortNo, Egress: ingressPortNo}
+				routes = append(routes, hop)
+				routes = append(routes, hop)
+				return routes, nil
+			}
+			//Return a 'half' route to make the flow decomposer logic happy
+			for routeLink, path := range agent.deviceRoutes.Routes {
+				if agent.isNNIPort(routeLink.Egress) {
+					routes = append(routes, route.Hop{}) // first hop is set to empty
+					routes = append(routes, path[1])
+					return routes, nil
+				}
+			}
+			return nil, fmt.Errorf("no upstream route from:%d to:%d :%w", ingressPortNo, egressPortNo, route.ErrNoRoute)
+		}
+		//treat it as if the output port is the first NNI of the OLT
+		var err error
+		if egressPortNo, err = agent.getFirstNNIPort(); err != nil {
+			logger.Warnw("no-nni-port", log.Fields{"error": err})
+			return nil, err
+		}
+	}
+	//If ingress port is not specified (nil), it may be a wildcarded
+	//route if egress port is OFPP_CONTROLLER or a nni logical port,
+	//in which case we need to create a half-route where only the egress
+	//hop is filled, the first hop is nil
+	if ingressPortNo == 0 && agent.isNNIPort(egressPortNo) {
+		// We can use the 2nd hop of any upstream route, so just find the first upstream:
+		for routeLink, path := range agent.deviceRoutes.Routes {
+			if agent.isNNIPort(routeLink.Egress) {
+				routes = append(routes, route.Hop{}) // first hop is set to empty
+				routes = append(routes, path[1])
+				return routes, nil
+			}
+		}
+		return nil, fmt.Errorf("no upstream route from:%d to:%d :%w", ingressPortNo, egressPortNo, route.ErrNoRoute)
+	}
+	//If egress port is not specified (nil), we can also can return a "half" route
+	if egressPortNo == 0 {
+		for routeLink, path := range agent.deviceRoutes.Routes {
+			if routeLink.Ingress == ingressPortNo {
+				routes = append(routes, path[0])
+				routes = append(routes, route.Hop{})
+				return routes, nil
+			}
+		}
+		return nil, fmt.Errorf("no downstream route from:%d to:%d :%w", ingressPortNo, egressPortNo, route.ErrNoRoute)
+	}
+	//	Return the pre-calculated route
+	return agent.getPreCalculatedRoute(ingressPortNo, egressPortNo)
+}
+
+func (agent *LogicalAgent) getPreCalculatedRoute(ingress, egress uint32) ([]route.Hop, error) {
+	logger.Debugw("ROUTE", log.Fields{"len": len(agent.deviceRoutes.Routes)})
+	for routeLink, route := range agent.deviceRoutes.Routes {
+		logger.Debugw("ROUTELINKS", log.Fields{"ingress": ingress, "egress": egress, "routelink": routeLink})
+		if ingress == routeLink.Ingress && egress == routeLink.Egress {
+			return route, nil
+		}
+	}
+	return nil, status.Errorf(codes.FailedPrecondition, "no route from:%d to:%d", ingress, egress)
+}
+
+// GetDeviceRoutes returns device graph
+func (agent *LogicalAgent) GetDeviceRoutes() *route.DeviceRoutes {
+	return agent.deviceRoutes
+}
+
+//generateDeviceRoutesIfNeeded generates the device routes if the logical device has been updated since the last time
+//that device graph was generated.
+func (agent *LogicalAgent) generateDeviceRoutesIfNeeded(ctx context.Context) error {
+	agent.lockDeviceRoutes.Lock()
+	defer agent.lockDeviceRoutes.Unlock()
+
+	ld, err := agent.GetLogicalDevice(ctx)
+	if err != nil {
+		return err
+	}
+
+	if agent.deviceRoutes != nil && agent.deviceRoutes.IsUpToDate(ld) {
+		return nil
+	}
+	logger.Debug("Generation of device route required")
+	if err := agent.buildRoutes(ctx); err != nil {
+		// No Route is not an error
+		if !errors.Is(err, route.ErrNoRoute) {
+			return err
+		}
+	}
+	return nil
+}
+
+//rebuildRoutes rebuilds the device routes
+func (agent *LogicalAgent) buildRoutes(ctx context.Context) error {
+	logger.Debugf("building-routes", log.Fields{"logical-device-id": agent.logicalDeviceID})
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return err
+	}
+	defer agent.requestQueue.RequestComplete()
+
+	if agent.deviceRoutes == nil {
+		agent.deviceRoutes = route.NewDeviceRoutes(agent.logicalDeviceID, agent.deviceMgr.getDevice)
+	}
+	// Get all the logical ports on that logical device
+	lDevice := agent.getLogicalDeviceWithoutLock()
+
+	if err := agent.deviceRoutes.ComputeRoutes(ctx, lDevice.Ports); err != nil {
+		return err
+	}
+	if err := agent.deviceRoutes.Print(); err != nil {
+		return err
+	}
+	return nil
+}
+
+//updateRoutes updates the device routes
+func (agent *LogicalAgent) updateRoutes(ctx context.Context, lp *voltha.LogicalPort) error {
+	logger.Debugw("updateRoutes", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return err
+	}
+	defer agent.requestQueue.RequestComplete()
+
+	if agent.deviceRoutes == nil {
+		agent.deviceRoutes = route.NewDeviceRoutes(agent.logicalDeviceID, agent.deviceMgr.getDevice)
+	}
+	if err := agent.deviceRoutes.AddPort(ctx, lp, agent.logicalDevice.Ports); err != nil {
+		return err
+	}
+	if err := agent.deviceRoutes.Print(); err != nil {
+		return err
+	}
+	return nil
+}
