[VOL-5164] - flow handling during port delete
Change-Id: I325dcf3719ce932d7fe05012c30c5f4c16552546
diff --git a/internal/pkg/application/application.go b/internal/pkg/application/application.go
index 0117cd7..3ddb29c 100644
--- a/internal/pkg/application/application.go
+++ b/internal/pkg/application/application.go
@@ -940,7 +940,8 @@
} else {
for _, vpv := range vpvs.([]*VoltPortVnet) {
vpv.VpvLock.Lock()
- vpv.PortDownInd(cntx, device, port, true)
+ // Set delFlowsInDevice to true to delete flows only in DB/device during Port Delete.
+ vpv.PortDownInd(cntx, device, port, true, true)
vpv.VpvLock.Unlock()
}
}
@@ -1501,7 +1502,7 @@
for _, vpv := range vpvs.([]*VoltPortVnet) {
vpv.VpvLock.Lock()
- vpv.PortDownInd(cntx, device, port, false)
+ vpv.PortDownInd(cntx, device, port, false, false)
if vpv.IgmpEnabled {
va.ReceiverDownInd(cntx, device, port)
}
diff --git a/internal/pkg/application/igmpprofiles.go b/internal/pkg/application/igmpprofiles.go
index a1d999c..2683a06 100644
--- a/internal/pkg/application/igmpprofiles.go
+++ b/internal/pkg/application/igmpprofiles.go
@@ -318,7 +318,7 @@
if err := mvp.WriteToDb(cntx); err != nil {
logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
}
- return cntlr.GetController().DelFlows(cntx, device.NniPort, device.Name, flow)
+ return cntlr.GetController().DelFlows(cntx, device.NniPort, device.Name, flow, false)
}
// FlowRemoveSuccess - Process flow success indication
diff --git a/internal/pkg/application/service.go b/internal/pkg/application/service.go
index e031b22..6c44450 100644
--- a/internal/pkg/application/service.go
+++ b/internal/pkg/application/service.go
@@ -292,12 +292,12 @@
// DelHsiaFlows - Deletes US & DS HSIA Flows for the service
func (vs *VoltService) DelHsiaFlows(cntx context.Context) {
logger.Debugw(ctx, "Delete US & DS HSIA Flows for the service", log.Fields{"ServiceName": vs.Name})
- if err := vs.DelUsHsiaFlows(cntx); err != nil {
+ if err := vs.DelUsHsiaFlows(cntx, false); err != nil {
statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
vs.triggerServiceFailureInd(statusCode, statusMessage)
}
- if err := vs.DelDsHsiaFlows(cntx); err != nil {
+ if err := vs.DelDsHsiaFlows(cntx, false); err != nil {
statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
vs.triggerServiceFailureInd(statusCode, statusMessage)
}
@@ -446,7 +446,7 @@
}
// DelUsHsiaFlows - Deletes US HSIA Flows for the service
-func (vs *VoltService) DelUsHsiaFlows(cntx context.Context) error {
+func (vs *VoltService) DelUsHsiaFlows(cntx context.Context, delFlowsInDevice bool) error {
logger.Infow(ctx, "Removing US HSIA Services", log.Fields{"Device": vs.Device, "ServiceName": vs.Name})
if vs.UsHSIAFlowsApplied || vgcRebooted {
device, err := GetApplication().GetDeviceFromPort(vs.Port)
@@ -468,7 +468,7 @@
continue
}
usflows.MigrateCookie = vgcRebooted
- if err = vs.DelFlows(cntx, device, usflows); err != nil {
+ if err = vs.DelFlows(cntx, device, usflows, delFlowsInDevice); err != nil {
logger.Errorw(ctx, "Error Deleting HSIA US flows", log.Fields{"Device": vs.Device, "ServiceName": vs.Name, "Reason": err.Error()})
statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
vs.triggerServiceFailureInd(statusCode, statusMessage)
@@ -481,7 +481,7 @@
}
// DelDsHsiaFlows - Deletes DS HSIA Flows for the service
-func (vs *VoltService) DelDsHsiaFlows(cntx context.Context) error {
+func (vs *VoltService) DelDsHsiaFlows(cntx context.Context, delFlowsInDevice bool) error {
logger.Infow(ctx, "Removing DS HSIA Services", log.Fields{"Device": vs.Device, "ServiceName": vs.Name})
if vs.DsHSIAFlowsApplied || vgcRebooted {
device, err := GetApplication().GetDeviceFromPort(vs.Port)
@@ -497,7 +497,7 @@
return fmt.Errorf("Error Building HSIA DS flows for Service %s and Port %s : %w", vs.Name, vs.Port, err)
}
dsflows.MigrateCookie = vgcRebooted
- if err = vs.DelFlows(cntx, device, dsflows); err != nil {
+ if err = vs.DelFlows(cntx, device, dsflows, delFlowsInDevice); err != nil {
logger.Errorw(ctx, "Error Deleting HSIA DS flows", log.Fields{"Device": vs.Device, "ServiceName": vs.Name, "Reason": err.Error()})
statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
vs.triggerServiceFailureInd(statusCode, statusMessage)
@@ -508,7 +508,7 @@
return fmt.Errorf("Error Building HSIA DS flows for Service %s and Port %s : %w", vs.Name, vs.Port, err)
}
dsflows.MigrateCookie = vgcRebooted
- if err = vs.DelFlows(cntx, device, dsflows); err != nil {
+ if err = vs.DelFlows(cntx, device, dsflows, delFlowsInDevice); err != nil {
logger.Errorw(ctx, "Error Deleting HSIA DS flows", log.Fields{"Device": vs.Device, "ServiceName": vs.Name, "Reason": err.Error()})
statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
vs.triggerServiceFailureInd(statusCode, statusMessage)
@@ -523,7 +523,7 @@
continue
}
dsflows.MigrateCookie = vgcRebooted
- if err = vs.DelFlows(cntx, device, dsflows); err != nil {
+ if err = vs.DelFlows(cntx, device, dsflows, delFlowsInDevice); err != nil {
logger.Errorw(ctx, "Error Deleting HSIA DS flows", log.Fields{"Device": vs.Device, "ServiceName": vs.Name, "Reason": err.Error()})
statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
vs.triggerServiceFailureInd(statusCode, statusMessage)
@@ -1338,7 +1338,7 @@
// DelFlows - Deletes the flow from the service
// Triggers flow deletion after registering for flow indication event
-func (vs *VoltService) DelFlows(cntx context.Context, device *VoltDevice, flow *of.VoltFlow) error {
+func (vs *VoltService) DelFlows(cntx context.Context, device *VoltDevice, flow *of.VoltFlow, delFlowsInDevice bool) error {
logger.Debugw(ctx, "Delete the flow from the service", log.Fields{"Port": vs.Port, "Device": device.Name})
if !vs.ForceDelete {
// Using locks instead of concurrent map for AssociatedFlows to avoid
@@ -1356,7 +1356,7 @@
device.RegisterFlowDelEvent(cookie, fe)
}
}
- return cntlr.GetController().DelFlows(cntx, vs.Port, device.Name, flow)
+ return cntlr.GetController().DelFlows(cntx, vs.Port, device.Name, flow, delFlowsInDevice)
}
// CheckAndDeleteService - remove service from DB is there are no pending flows to be removed
@@ -1967,13 +1967,13 @@
// This case happens only in case of some race condition
logger.Infow(ctx, "Trigger Associated Flow Delete", log.Fields{"Device": vs.Device, "Service": vs.Name})
if vs.UsHSIAFlowsApplied {
- if err := vs.DelUsHsiaFlows(cntx); err != nil {
+ if err := vs.DelUsHsiaFlows(cntx, false); err != nil {
logger.Warnw(ctx, "DelUsHsiaFlows Failed", log.Fields{"Device": vs.Device, "Service": vs.Name, "Error": err})
}
}
if vs.DsHSIAFlowsApplied {
- if err := vs.DelDsHsiaFlows(cntx); err != nil {
+ if err := vs.DelDsHsiaFlows(cntx, false); err != nil {
logger.Warnw(ctx, "DelDsHsiaFlows Failed", log.Fields{"Device": vs.Device, "Service": vs.Name, "Error": err})
}
}
@@ -1998,7 +1998,7 @@
subFlow.Cookie = cookie
flow.SubFlows[cookie] = subFlow
logger.Infow(ctx, "Retriggering Service Delete Flow", log.Fields{"Device": vs.Device, "Service": vs.Name, "Cookie": cookie})
- if err := vs.DelFlows(cntx, vd, flow); err != nil {
+ if err := vs.DelFlows(cntx, vd, flow, false); err != nil {
logger.Warnw(ctx, "DelFlows Failed", log.Fields{"Device": vs.Device, "Service": vs.Name, "Cookie": cookie, "Error": err})
}
}
@@ -2184,7 +2184,7 @@
if p != nil && (p.State == PortStateUp || !va.OltFlowServiceConfig.RemoveFlowsOnDisable) {
if vpv := va.GetVnetByPort(vs.Port, vs.SVlan, vs.CVlan, vs.UniVlan); vpv != nil {
// Port down call internally deletes all the flows
- vpv.PortDownInd(cntx, deviceID, portNo, true)
+ vpv.PortDownInd(cntx, deviceID, portNo, true, false)
if vpv.IgmpEnabled {
va.ReceiverDownInd(cntx, deviceID, portNo)
}
diff --git a/internal/pkg/application/vnets.go b/internal/pkg/application/vnets.go
index df89c68..72c43fd 100644
--- a/internal/pkg/application/vnets.go
+++ b/internal/pkg/application/vnets.go
@@ -674,9 +674,9 @@
}
// RangeOnServices to call a function on all services on the vpv
-func (vpv *VoltPortVnet) RangeOnServices(cntx context.Context, callback func(cntx context.Context, key, value interface{}) bool) {
+func (vpv *VoltPortVnet) RangeOnServices(cntx context.Context, callback func(cntx context.Context, key, value interface{}, flag bool) bool, delFlowsInDevice bool) {
vpv.services.Range(func(key, value interface{}) bool {
- return callback(cntx, key, value)
+ return callback(cntx, key, value, delFlowsInDevice)
})
}
@@ -689,7 +689,7 @@
vpv.Ipv4Addr, _ = GetIpv4Addr(res)
logger.Debugw(ctx, "Received IPv4 Address and Services Configured", log.Fields{"IP Address": vpv.Ipv4Addr.String(), "Count": vpv.servicesCount.Load()})
- vpv.RangeOnServices(cntx, vpv.updateIPv4AndProvisionFlows)
+ vpv.RangeOnServices(cntx, vpv.updateIPv4AndProvisionFlows, false)
vpv.ProcessDhcpv4Options(res)
}
@@ -717,12 +717,12 @@
vpv.Dhcp6ExpiryTime = time.Now().Add((time.Duration(leaseTime) * time.Second))
vpv.Ipv6Addr = ipv6Addr
- vpv.RangeOnServices(cntx, vpv.updateIPv6AndProvisionFlows)
+ vpv.RangeOnServices(cntx, vpv.updateIPv6AndProvisionFlows, false)
vpv.WriteToDb(cntx)
}
// AddSvcUsMeterToDevice to add service upstream meter info to device
-func AddSvcUsMeterToDevice(cntx context.Context, key, value interface{}) bool {
+func AddSvcUsMeterToDevice(cntx context.Context, key, value interface{}, flag bool) bool {
svc := value.(*VoltService)
logger.Infow(ctx, "Adding upstream meter profile to device", log.Fields{"ServiceName": svc.Name})
if device, _ := GetApplication().GetDeviceFromPort(svc.Port); device != nil {
@@ -794,23 +794,23 @@
logger.Infow(ctx, "Port Up - Trap Flows", log.Fields{"Device": device.Name, "Port": port})
// no HSIA flows for multicast service and DPU_MGMT Service
if !vpv.McastService && vpv.VnetType != DpuMgmtTraffic {
- vpv.RangeOnServices(cntx, AddUsHsiaFlows)
+ vpv.RangeOnServices(cntx, AddUsHsiaFlows, false)
}
if vpv.VnetType == DpuMgmtTraffic {
- vpv.RangeOnServices(cntx, AddMeterToDevice)
+ vpv.RangeOnServices(cntx, AddMeterToDevice, false)
}
vpv.AddTrapFlows(cntx)
if vpv.MacLearning == MacLearningNone || NonZeroMacAddress(vpv.MacAddr) {
logger.Infow(ctx, "Port Up - DS Flows", log.Fields{"Device": device.Name, "Port": port})
/*In case of DPU_MGMT_TRAFFIC, need to install both US and DS traffic */
if vpv.VnetType == DpuMgmtTraffic {
- vpv.RangeOnServices(cntx, AddUsHsiaFlows)
+ vpv.RangeOnServices(cntx, AddUsHsiaFlows, false)
}
// US & DS DHCP, US HSIA flows are already installed
// install only DS HSIA flow here.
// no HSIA flows for multicast service
if !vpv.McastService {
- vpv.RangeOnServices(cntx, AddDsHsiaFlows)
+ vpv.RangeOnServices(cntx, AddDsHsiaFlows, false)
}
}
} else {
@@ -821,25 +821,25 @@
// however is not seen as a real use case.
logger.Infow(ctx, "Port Up - Service Flows", log.Fields{"Device": device.Name, "Port": port})
if !vpv.McastService {
- vpv.RangeOnServices(cntx, AddUsHsiaFlows)
+ vpv.RangeOnServices(cntx, AddUsHsiaFlows, false)
}
vpv.AddTrapFlows(cntx)
if !vpv.McastService {
- vpv.RangeOnServices(cntx, AddDsHsiaFlows)
+ vpv.RangeOnServices(cntx, AddDsHsiaFlows, false)
}
}
// Process IGMP proxy - install IGMP trap rules before DHCP trap rules
if vpv.IgmpEnabled {
logger.Infow(ctx, "Port Up - IGMP Flows", log.Fields{"Device": device.Name, "Port": port})
- vpv.RangeOnServices(cntx, AddSvcUsMeterToDevice)
+ vpv.RangeOnServices(cntx, AddSvcUsMeterToDevice, false)
if err := vpv.AddIgmpFlows(cntx); err != nil {
statusCode, statusMessage := errorCodes.GetErrorInfo(err)
vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
}
if vpv.McastService {
- vpv.RangeOnServices(cntx, PostAccessConfigSuccessInd)
+ vpv.RangeOnServices(cntx, PostAccessConfigSuccessInd, false)
}
}
@@ -849,7 +849,8 @@
// PortDownInd : When the port status changes to down, we delete all configured flows
// The same indication is also passed to the services enqueued for them
// to take appropriate actions
-func (vpv *VoltPortVnet) PortDownInd(cntx context.Context, device string, port string, nbRequest bool) {
+// delFlowsInDevice flag indicates that flows should be deleted only in DB/device and should not be forwarded to core
+func (vpv *VoltPortVnet) PortDownInd(cntx context.Context, device string, port string, nbRequest bool, delFlowsInDevice bool) {
if !nbRequest && !GetApplication().OltFlowServiceConfig.RemoveFlowsOnDisable {
logger.Info(ctx, "VPV Port DOWN Ind, Not deleting flows since RemoveOnDisable is disabled")
return
@@ -859,7 +860,7 @@
//vpv.RangeOnServices(cntx, DelAllFlows)
vpv.DelTrapFlows(cntx)
- vpv.DelHsiaFlows(cntx)
+ vpv.DelHsiaFlows(cntx, delFlowsInDevice)
vpv.WriteToDb(cntx)
vpv.ClearServiceCounters(cntx)
}
@@ -895,15 +896,15 @@
// may have been changed
// Atleast one HSIA flow should be present in adapter to retain the TP and GEM
// hence delete one after the other
- vpv.RangeOnServices(cntx, DelUsHsiaFlows)
+ vpv.RangeOnServices(cntx, DelUsHsiaFlows, false)
vpv.MacAddr = addr
- vpv.RangeOnServices(cntx, vpv.setLearntMAC)
- vpv.RangeOnServices(cntx, AddUsHsiaFlows)
- vpv.RangeOnServices(cntx, DelDsHsiaFlows)
+ vpv.RangeOnServices(cntx, vpv.setLearntMAC, false)
+ vpv.RangeOnServices(cntx, AddUsHsiaFlows, false)
+ vpv.RangeOnServices(cntx, DelDsHsiaFlows, false)
GetApplication().DeleteMacInPortMap(vpv.MacAddr)
} else {
vpv.MacAddr = addr
- vpv.RangeOnServices(cntx, vpv.setLearntMAC)
+ vpv.RangeOnServices(cntx, vpv.setLearntMAC, false)
logger.Infow(ctx, "MAC Address learnt from DHCP or ARP", log.Fields{"Learnt MAC": addr.String(), "Port": vpv.Port})
}
GetApplication().UpdateMacInPortMap(vpv.MacAddr, vpv.Port)
@@ -922,11 +923,11 @@
if vpv.FlowsApplied {
// In case of DPU_MGMT_TRAFFIC install both US and DS Flows
if vpv.VnetType == DpuMgmtTraffic {
- vpv.RangeOnServices(cntx, AddUsHsiaFlows)
+ vpv.RangeOnServices(cntx, AddUsHsiaFlows, false)
}
// no HSIA flows for multicast service
if !vpv.McastService {
- vpv.RangeOnServices(cntx, AddDsHsiaFlows)
+ vpv.RangeOnServices(cntx, AddDsHsiaFlows, false)
}
}
vpv.WriteToDb(cntx)
@@ -1105,14 +1106,14 @@
if vpv.McastService {
// For McastService, send Service Activated indication once IGMP US flow is pushed
- vpv.RangeOnServices(cntx, PostAccessConfigSuccessInd)
+ vpv.RangeOnServices(cntx, PostAccessConfigSuccessInd, false)
}
}
vpv.WriteToDb(cntx)
}
// setLearntMAC to set learnt mac
-func (vpv *VoltPortVnet) setLearntMAC(cntx context.Context, key, value interface{}) bool {
+func (vpv *VoltPortVnet) setLearntMAC(cntx context.Context, key, value interface{}, flag bool) bool {
svc := value.(*VoltService)
svc.SetMacAddr(vpv.MacAddr)
svc.WriteToDb(cntx)
@@ -1120,12 +1121,12 @@
}
// PostAccessConfigSuccessInd for posting access config success indication
-func PostAccessConfigSuccessInd(cntx context.Context, key, value interface{}) bool {
+func PostAccessConfigSuccessInd(cntx context.Context, key, value interface{}, flag bool) bool {
return true
}
// updateIPv4AndProvisionFlows to update ipv4 and provisional flows
-func (vpv *VoltPortVnet) updateIPv4AndProvisionFlows(cntx context.Context, key, value interface{}) bool {
+func (vpv *VoltPortVnet) updateIPv4AndProvisionFlows(cntx context.Context, key, value interface{}, flag bool) bool {
svc := value.(*VoltService)
logger.Debugw(ctx, "Updating Ipv4 address for service", log.Fields{"ServiceName": svc.Name})
svc.SetIpv4Addr(vpv.Ipv4Addr)
@@ -1135,7 +1136,7 @@
}
// updateIPv6AndProvisionFlows to update ipv6 and provisional flow
-func (vpv *VoltPortVnet) updateIPv6AndProvisionFlows(cntx context.Context, key, value interface{}) bool {
+func (vpv *VoltPortVnet) updateIPv6AndProvisionFlows(cntx context.Context, key, value interface{}, flag bool) bool {
svc := value.(*VoltService)
logger.Debugw(ctx, "Updating Ipv6 address for service", log.Fields{"ServiceName": svc.Name})
svc.SetIpv6Addr(vpv.Ipv6Addr)
@@ -1145,7 +1146,7 @@
}
// AddUsHsiaFlows to add upstream hsia flows
-func AddUsHsiaFlows(cntx context.Context, key, value interface{}) bool {
+func AddUsHsiaFlows(cntx context.Context, key, value interface{}, flag bool) bool {
svc := value.(*VoltService)
logger.Debugw(ctx, "Add US Hsia Flows", log.Fields{"ServiceName": svc.Name})
if err := svc.AddUsHsiaFlows(cntx); err != nil {
@@ -1155,7 +1156,7 @@
}
// AddDsHsiaFlows to add downstream hsia flows
-func AddDsHsiaFlows(cntx context.Context, key, value interface{}) bool {
+func AddDsHsiaFlows(cntx context.Context, key, value interface{}, flag bool) bool {
svc := value.(*VoltService)
logger.Debugw(ctx, "Add DS Hsia Flows", log.Fields{"ServiceName": svc.Name})
if err := svc.AddDsHsiaFlows(cntx); err != nil {
@@ -1165,7 +1166,7 @@
}
// ClearFlagsInService to clear the flags used in service
-func ClearFlagsInService(cntx context.Context, key, value interface{}) bool {
+func ClearFlagsInService(cntx context.Context, key, value interface{}, flag bool) bool {
svc := value.(*VoltService)
logger.Debugw(ctx, "Received Cleared Flow Flags for service", log.Fields{"name": svc.Name})
svc.ServiceLock.Lock()
@@ -1184,27 +1185,29 @@
}
// DelDsHsiaFlows to delete hsia flows
-func DelDsHsiaFlows(cntx context.Context, key, value interface{}) bool {
+// delFlowsInDevice flag indicates that flows should be deleted only in DB/device and should not be forwarded to core
+func DelDsHsiaFlows(cntx context.Context, key, value interface{}, delFlowsInDevice bool) bool {
svc := value.(*VoltService)
logger.Debugw(ctx, "Delete DS Hsia Flows", log.Fields{"ServiceName": svc.Name})
- if err := svc.DelDsHsiaFlows(cntx); err != nil {
+ if err := svc.DelDsHsiaFlows(cntx, delFlowsInDevice); err != nil {
logger.Warnw(ctx, "Delete DS hsia flow failed", log.Fields{"service": svc.Name, "Error": err})
}
return true
}
// DelUsHsiaFlows to delete upstream hsia flows
-func DelUsHsiaFlows(cntx context.Context, key, value interface{}) bool {
+// delFlowsInDevice flag indicates that flows should be deleted only in DB/device and should not be forwarded to core
+func DelUsHsiaFlows(cntx context.Context, key, value interface{}, delFlowsInDevice bool) bool {
svc := value.(*VoltService)
logger.Debugw(ctx, "Delete US Hsia Flows", log.Fields{"ServiceName": svc.Name})
- if err := svc.DelUsHsiaFlows(cntx); err != nil {
+ if err := svc.DelUsHsiaFlows(cntx, delFlowsInDevice); err != nil {
logger.Warnw(ctx, "Delete US hsia flow failed", log.Fields{"service": svc.Name, "Error": err})
}
return true
}
// ClearServiceCounters to clear the service counters
-func ClearServiceCounters(cntx context.Context, key, value interface{}) bool {
+func ClearServiceCounters(cntx context.Context, key, value interface{}, flag bool) bool {
svc := value.(*VoltService)
logger.Debugw(ctx, "Received Clear Service Counters", log.Fields{"ServiceName": svc.Name})
//Delete the per service counter too
@@ -1216,7 +1219,7 @@
}
// AddMeterToDevice to add meter config to device, used in FTTB case
-func AddMeterToDevice(cntx context.Context, key, value interface{}) bool {
+func AddMeterToDevice(cntx context.Context, key, value interface{}, flag bool) bool {
svc := value.(*VoltService)
logger.Debugw(ctx, "Received Add Meter To Device", log.Fields{"ServiceName": svc.Name})
if err := svc.AddMeterToDevice(cntx); err != nil {
@@ -1304,19 +1307,19 @@
}
// DelHsiaFlows deletes the service flows
-func (vpv *VoltPortVnet) DelHsiaFlows(cntx context.Context) {
+func (vpv *VoltPortVnet) DelHsiaFlows(cntx context.Context, delFlowsInDevice bool) {
logger.Infow(ctx, "Received Delete Hsia Flows", log.Fields{"McastService": vpv.McastService})
// no HSIA flows for multicast service
if !vpv.McastService {
- vpv.RangeOnServices(cntx, DelUsHsiaFlows)
- vpv.RangeOnServices(cntx, DelDsHsiaFlows)
+ vpv.RangeOnServices(cntx, DelUsHsiaFlows, delFlowsInDevice)
+ vpv.RangeOnServices(cntx, DelDsHsiaFlows, delFlowsInDevice)
}
}
// ClearServiceCounters - Removes all igmp counters for a service
func (vpv *VoltPortVnet) ClearServiceCounters(cntx context.Context) {
//send flows deleted indication to submgr
- vpv.RangeOnServices(cntx, ClearServiceCounters)
+ vpv.RangeOnServices(cntx, ClearServiceCounters, false)
}
// AddUsDhcpFlows pushes the DHCP flows to the VOLTHA via the controller
@@ -2155,7 +2158,7 @@
// ClearAllServiceFlags to clear all service flags
func (vpv *VoltPortVnet) ClearAllServiceFlags(cntx context.Context) {
- vpv.RangeOnServices(cntx, ClearFlagsInService)
+ vpv.RangeOnServices(cntx, ClearFlagsInService, false)
}
// ClearAllVpvFlags to clear all vpv flags
@@ -2312,7 +2315,7 @@
va.VnetsByPort.Store(port, vpvs)
vpv.DelTrapFlows(cntx)
- vpv.DelHsiaFlows(cntx)
+ vpv.DelHsiaFlows(cntx, false)
va.DisassociateVpvsFromDevice(vpv.Device, vpv)
vpv.PendingFlowLock.RLock()
if len(vpv.PendingDeleteFlow) == 0 {
@@ -2926,7 +2929,7 @@
device.RegisterFlowDelEvent(cookie, fe)
vpv.PendingDeleteFlow[cookie] = true
}
- return cntlr.GetController().DelFlows(cntx, vpv.Port, device.Name, flow)
+ return cntlr.GetController().DelFlows(cntx, vpv.Port, device.Name, flow, false)
}
// CheckAndDeleteVpv - remove VPV from DB is there are no pending flows to be removed
@@ -3005,7 +3008,7 @@
vv.PendingDeleteFlow[device.Name] = flowMap
}
vv.WriteToDb(cntx)
- return cntlr.GetController().DelFlows(cntx, device.NniPort, device.Name, flow)
+ return cntlr.GetController().DelFlows(cntx, device.NniPort, device.Name, flow, false)
}
// CheckAndDeleteVnet - remove Vnet from DB is there are no pending flows to be removed
diff --git a/internal/pkg/controller/controller.go b/internal/pkg/controller/controller.go
index b1939b9..9ccb21d 100644
--- a/internal/pkg/controller/controller.go
+++ b/internal/pkg/controller/controller.go
@@ -313,7 +313,8 @@
}
// DelFlows to delete flows
-func (v *VoltController) DelFlows(cntx context.Context, port string, device string, flow *of.VoltFlow) error {
+// delFlowsOnlyInDevice flag indicates that flows should be deleted only in DB/device and should not be forwarded to core
+func (v *VoltController) DelFlows(cntx context.Context, port string, device string, flow *of.VoltFlow, delFlowsOnlyInDevice bool) error {
d, err := v.GetDevice(device)
if err != nil {
logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
@@ -351,10 +352,18 @@
}
}
} else {
- flow.Command = of.CommandDel
- d.UpdateFlows(flow, devPort)
- for cookie := range flow.SubFlows {
- logger.Debugw(ctx, "Flow Del added to queue", log.Fields{"Cookie": cookie, "Device": device, "Port": port})
+ // Delete flows only in DB/device when Port Delete has come. Do not send flows to core during Port Delete
+ if delFlowsOnlyInDevice {
+ for cookie, subFlow := range flow.SubFlows {
+ err := d.DelFlow(ctx, subFlow)
+ logger.Infow(ctx, "Flow Deleted from device/DB", log.Fields{"Cookie": cookie, "Device": device, "Port": port, "Error": err})
+ }
+ } else {
+ flow.Command = of.CommandDel
+ d.UpdateFlows(flow, devPort)
+ for cookie := range flow.SubFlows {
+ logger.Debugw(ctx, "Flow Del added to queue", log.Fields{"Cookie": cookie, "Device": device, "Port": port})
+ }
}
}
return nil
diff --git a/internal/pkg/controller/controller_test.go b/internal/pkg/controller/controller_test.go
index ff45c50..2c4b993 100644
--- a/internal/pkg/controller/controller_test.go
+++ b/internal/pkg/controller/controller_test.go
@@ -238,7 +238,7 @@
v := &VoltController{
devices: dev,
}
- if err := v.DelFlows(tt.args.cntx, tt.args.port, tt.args.device, tt.args.flow); (err != nil) != tt.wantErr {
+ if err := v.DelFlows(tt.args.cntx, tt.args.port, tt.args.device, tt.args.flow, false); (err != nil) != tt.wantErr {
t.Errorf("VoltController.DelFlows() error = %v, wantErr %v", err, tt.wantErr)
}
})