diff --git a/internal/pkg/application/application.go b/internal/pkg/application/application.go
index 73a88a9..85f06be 100644
--- a/internal/pkg/application/application.go
+++ b/internal/pkg/application/application.go
@@ -146,13 +146,13 @@
 // as the identity. The SB is abstracted by VPAgent and the VPAgent transacts
 // using name as identity
 type VoltPort struct {
-	ID                       uint32
 	Name                     string
 	Device                   string
 	PonPort                  uint32
+	ActiveChannels           uint32
+	ID                       uint32
 	Type                     VoltPortType
 	State                    PortState
-	ActiveChannels           uint32
 	ChannelPerSubAlarmRaised bool
 }
 
@@ -191,31 +191,31 @@
 
 // VoltDevice fields :
 // Name:         This is the name presented by the device/VOLTHA. This doesn't
-//               have any relation to the physical device
+// have any relation to the physical device
 // SerialNum:    This is the serial number of the device and can be used to
-//               correlate the devices
+// correlate the devices
 // NniPort:      The identity of the NNI port
 // Ports:        List of all ports added to the device
 type VoltDevice struct {
-	Name                         string
-	SerialNum                    string
-	State                        controller.DeviceState
-	SouthBoundID                 string
-	NniPort                      string
-	Ports                        sync.Map
-	VlanPortStatus               sync.Map
-	VpvsBySvlan                  *util.ConcurrentMap // map[svlan]map[vnet_port]*VoltPortVnet
-	IgmpDsFlowAppliedForMvlan    map[uint16]bool
-	ConfiguredVlanForDeviceFlows *util.ConcurrentMap //map[string]map[string]bool
-	icmpv6GroupAdded             bool
-	ActiveChannelsPerPon         sync.Map            // [PonPortID]*PonPortCfg
-	ActiveChannelCountLock       sync.Mutex          // This lock is used to update ActiveIGMPChannels
-	PonPortList                  sync.Map            // [PonPortID]map[string]string
 	FlowAddEventMap              *util.ConcurrentMap //map[string]*FlowEvent
 	FlowDelEventMap              *util.ConcurrentMap //map[string]*FlowEvent
 	MigratingServices            *util.ConcurrentMap //<vnetID,<RequestID, MigrateServicesRequest>>
-	GlobalDhcpFlowAdded          bool
+	VpvsBySvlan                  *util.ConcurrentMap // map[svlan]map[vnet_port]*VoltPortVnet
+	ConfiguredVlanForDeviceFlows *util.ConcurrentMap //map[string]map[string]bool
+	IgmpDsFlowAppliedForMvlan    map[uint16]bool
+	State                        controller.DeviceState
+	SouthBoundID                 string
+	NniPort                      string
+	Name                         string
+	SerialNum                    string
+	Ports                        sync.Map
+	VlanPortStatus               sync.Map
+	ActiveChannelsPerPon         sync.Map   // [PonPortID]*PonPortCfg
+	PonPortList                  sync.Map   // [PonPortID]map[string]string
+	ActiveChannelCountLock       sync.Mutex // This lock is used to update ActiveIGMPChannels
 	NniDhcpTrapVid               of.VlanType
+	GlobalDhcpFlowAdded          bool
+	icmpv6GroupAdded             bool
 }
 
 // NewVoltDevice : Constructor for the device
@@ -243,7 +243,7 @@
 	return &d
 }
 
-//GetAssociatedVpvsForDevice - return the associated VPVs for given device & svlan
+// GetAssociatedVpvsForDevice - return the associated VPVs for given device & svlan
 func (va *VoltApplication) GetAssociatedVpvsForDevice(device string, svlan of.VlanType) *util.ConcurrentMap {
 	if d := va.GetDevice(device); d != nil {
 		return d.GetAssociatedVpvs(svlan)
@@ -251,10 +251,9 @@
 	return nil
 }
 
-//AssociateVpvsToDevice - updates the associated VPVs for given device & svlan
+// AssociateVpvsToDevice - updates the associated VPVs for given device & svlan
 func (va *VoltApplication) AssociateVpvsToDevice(device string, vpv *VoltPortVnet) {
 	if d := va.GetDevice(device); d != nil {
-
 		vpvMap := d.GetAssociatedVpvs(vpv.SVlan)
 		vpvMap.Set(vpv, true)
 		d.VpvsBySvlan.Set(vpv.SVlan, vpvMap)
@@ -264,7 +263,7 @@
 	logger.Errorw(ctx, "Set VPVMap failed: Device Not Found", log.Fields{"Svlan": vpv.SVlan, "Device": device})
 }
 
-//DisassociateVpvsFromDevice - disassociated VPVs from given device & svlan
+// DisassociateVpvsFromDevice - disassociated VPVs from given device & svlan
 func (va *VoltApplication) DisassociateVpvsFromDevice(device string, vpv *VoltPortVnet) {
 	if d := va.GetDevice(device); d != nil {
 		vpvMap := d.GetAssociatedVpvs(vpv.SVlan)
@@ -276,9 +275,8 @@
 	logger.Errorw(ctx, "Remove VPVMap failed: Device Not Found", log.Fields{"Svlan": vpv.SVlan, "Device": device})
 }
 
-//GetAssociatedVpvs - returns the associated VPVs for the given Svlan
+// GetAssociatedVpvs - returns the associated VPVs for the given Svlan
 func (d *VoltDevice) GetAssociatedVpvs(svlan of.VlanType) *util.ConcurrentMap {
-
 	var vpvMap *util.ConcurrentMap
 	var mapIntf interface{}
 	var ok bool
@@ -358,7 +356,6 @@
 
 // pushFlowsForUnis to send port-up-indication for uni ports.
 func (d *VoltDevice) pushFlowsForUnis(cntx context.Context) {
-
 	logger.Info(ctx, "NNI Discovered, Sending Port UP Ind for UNIs")
 	d.Ports.Range(func(key, value interface{}) bool {
 		port := key.(string)
@@ -380,7 +377,6 @@
 			vpv.VpvLock.Lock()
 			vpv.PortUpInd(cntx, d, port)
 			vpv.VpvLock.Unlock()
-
 		}
 		return true
 	})
@@ -398,57 +394,56 @@
 
 // VoltApplication fields :
 // ServiceByName - Stores the services by the name as key
-//                 A record of NB configuration.
+// A record of NB configuration.
 // VnetsByPort   - Stores the VNETs by the ports configured
-//                 from NB. A record of NB configuration.
+// from NB. A record of NB configuration.
 // VnetsByTag    - Stores the VNETs by the VLANS configured
-//                 from NB. A record of NB configuration.
+// from NB. A record of NB configuration.
 // VnetsByName   - Stores the VNETs by the name configured
-//                 from NB. A record of NB configuration.
+// from NB. A record of NB configuration.
 // DevicesDisc   - Stores the devices discovered from SB.
-//                 Should be updated only by events from SB
+// Should be updated only by events from SB
 // PortsDisc     - Stores the ports discovered from SB.
-//                 Should be updated only by events from SB
+// Should be updated only by events from SB
 type VoltApplication struct {
-	ServiceByName       sync.Map // [serName]*VoltService
-	VnetsByPort         sync.Map // [portName][]*VoltPortVnet
-	VnetsByTag          sync.Map // [svlan-cvlan-uvlan]*VoltVnet
-	VnetsByName         sync.Map // [vnetName]*VoltVnet
-	VnetsBySvlan        *util.ConcurrentMap
-	DevicesDisc         sync.Map
-	PortsDisc           sync.Map
-	IgmpGroups          sync.Map // [grpKey]*IgmpGroup
-	IgmpGroupIds        []*IgmpGroup
-	MvlanProfilesByTag  sync.Map
-	MvlanProfilesByName sync.Map
-	Icmpv6Receivers     sync.Map
 	MeterMgr
-	IgmpTasks           tasks.Tasks
-	IndicationsTasks    tasks.Tasks
-	MulticastAlarmTasks tasks.Tasks
-	portLock            sync.Mutex
-	DataMigrationInfo   DataMigration
-	DeviceCounters      sync.Map //[logicalDeviceId]*DeviceCounters
-	ServiceCounters     sync.Map //[serviceName]*ServiceCounters
-	NbDevice            sync.Map // [OLTSouthBoundID]*NbDevice
-	IgmpKPIsTasks       tasks.Tasks
-	pppoeTasks          tasks.Tasks
-	IgmpProfilesByName  sync.Map
-	OltIgmpInfoBySerial sync.Map
-	McastConfigMap      sync.Map //[OltSerialNo_MvlanProfileID]*McastConfig
-	// MacAddress-Port MAP to avoid swap of mac accross ports.
-	macPortLock sync.RWMutex
-	macPortMap  map[string]string
-
+	DataMigrationInfo     DataMigration
+	VnetsBySvlan          *util.ConcurrentMap
+	IgmpGroupIds          []*IgmpGroup
+	VoltPortVnetsToDelete map[*VoltPortVnet]bool
 	IgmpPendingPool       map[string]map[*IgmpGroup]bool //[grpkey, map[groupObj]bool]  //mvlan_grpName/IP
-	PendingPoolLock       sync.RWMutex
+	macPortMap            map[string]string
 	VnetsToDelete         map[string]bool
 	ServicesToDelete      map[string]bool
-	VoltPortVnetsToDelete map[*VoltPortVnet]bool
 	PortAlarmProfileCache map[string]map[string]int // [portAlarmID][ThresholdLevelString]ThresholdLevel
 	vendorID              string
-	OltFlowServiceConfig  OltFlowService
+	ServiceByName         sync.Map // [serName]*VoltService
+	VnetsByPort           sync.Map // [portName][]*VoltPortVnet
+	VnetsByTag            sync.Map // [svlan-cvlan-uvlan]*VoltVnet
+	VnetsByName           sync.Map // [vnetName]*VoltVnet
+	DevicesDisc           sync.Map
+	PortsDisc             sync.Map
+	IgmpGroups            sync.Map // [grpKey]*IgmpGroup
+	MvlanProfilesByTag    sync.Map
+	MvlanProfilesByName   sync.Map
+	Icmpv6Receivers       sync.Map
+	DeviceCounters        sync.Map //[logicalDeviceId]*DeviceCounters
+	ServiceCounters       sync.Map //[serviceName]*ServiceCounters
+	NbDevice              sync.Map // [OLTSouthBoundID]*NbDevice
+	OltIgmpInfoBySerial   sync.Map
+	McastConfigMap        sync.Map //[OltSerialNo_MvlanProfileID]*McastConfig
 	DevicesConfig         sync.Map //[serialNumber]*DeviceConfig
+	IgmpProfilesByName    sync.Map
+	IgmpTasks             tasks.Tasks
+	IndicationsTasks      tasks.Tasks
+	MulticastAlarmTasks   tasks.Tasks
+	IgmpKPIsTasks         tasks.Tasks
+	pppoeTasks            tasks.Tasks
+	OltFlowServiceConfig  OltFlowService
+	PendingPoolLock       sync.RWMutex
+	// MacAddress-Port MAP to avoid swap of mac across ports.
+	macPortLock sync.RWMutex
+	portLock    sync.Mutex
 }
 
 type DeviceConfig struct {
@@ -462,11 +457,11 @@
 
 // PonPortCfg contains NB port config and activeIGMPChannels count
 type PonPortCfg struct {
+	PortAlarmProfileID string
 	PortID             uint32
 	MaxActiveChannels  uint32
 	ActiveIGMPChannels uint32
 	EnableMulticastKPI bool
-	PortAlarmProfileID string
 }
 
 // NbDevice OLT Device info
@@ -477,7 +472,6 @@
 
 // RestoreNbDeviceFromDb restores the NB Device in case of VGC pod restart.
 func (va *VoltApplication) RestoreNbDeviceFromDb(cntx context.Context, deviceID string) *NbDevice {
-
 	nbDevice := NewNbDevice()
 	nbDevice.SouthBoundID = deviceID
 
@@ -522,7 +516,6 @@
 // AddPortToNbDevice Adds pon port to NB Device and DB
 func (nbd *NbDevice) AddPortToNbDevice(cntx context.Context, portID, allowedChannels uint32,
 	enableMulticastKPI bool, portAlarmProfileID string) *PonPortCfg {
-
 	ponPort := &PonPortCfg{
 		PortID:             portID,
 		MaxActiveChannels:  allowedChannels,
@@ -554,7 +547,6 @@
 		if err := va.AddDeviceConfig(cntx, devConfig.SerialNumber, devConfig.HardwareIdentifier, devConfig.NasID, devConfig.IPAddress, devConfig.UplinkPort, devConfig.NniDhcpTrapVid); err != nil {
 			logger.Warnw(ctx, "Add device config failed", log.Fields{"DeviceConfig": devConfig, "Error": err})
 		}
-
 	}
 }
 
@@ -573,7 +565,7 @@
 	return nil
 }
 
-func (va *VoltApplication) AddDeviceConfig(cntx context.Context, serialNum, hardwareIdentifier, nasID, ipAddress, uplinkPort string, nniDhcpTrapId int) error {
+func (va *VoltApplication) AddDeviceConfig(cntx context.Context, serialNum, hardwareIdentifier, nasID, ipAddress, uplinkPort string, nniDhcpTrapID int) error {
 	var dc *DeviceConfig
 
 	deviceConfig := &DeviceConfig{
@@ -582,7 +574,7 @@
 		NasID:              nasID,
 		UplinkPort:         uplinkPort,
 		IPAddress:          ipAddress,
-		NniDhcpTrapVid:     nniDhcpTrapId,
+		NniDhcpTrapVid:     nniDhcpTrapID,
 	}
 	va.DevicesConfig.Store(serialNum, deviceConfig)
 	err := dc.WriteDeviceConfigToDb(cntx, serialNum, deviceConfig)
@@ -594,7 +586,7 @@
 	// If device is already discovered update the VoltDevice structure
 	device, id := va.GetDeviceBySerialNo(serialNum)
 	if device != nil {
-		device.NniDhcpTrapVid = of.VlanType(nniDhcpTrapId)
+		device.NniDhcpTrapVid = of.VlanType(nniDhcpTrapID)
 		va.DevicesDisc.Store(id, device)
 	}
 
@@ -611,7 +603,6 @@
 
 // UpdatePortToNbDevice Adds pon port to NB Device and DB
 func (nbd *NbDevice) UpdatePortToNbDevice(cntx context.Context, portID, allowedChannels uint32, enableMulticastKPI bool, portAlarmProfileID string) *PonPortCfg {
-
 	p, exists := nbd.PonPorts.Load(portID)
 	if !exists {
 		logger.Errorw(ctx, "PON port not exists in nb-device", log.Fields{"portID": portID})
@@ -631,7 +622,6 @@
 
 // DeletePortFromNbDevice Deletes pon port from NB Device and DB
 func (nbd *NbDevice) DeletePortFromNbDevice(cntx context.Context, portID uint32) {
-
 	if _, ok := nbd.PonPorts.Load(portID); ok {
 		nbd.PonPorts.Delete(portID)
 	}
@@ -670,9 +660,8 @@
 	return &va
 }
 
-//GetFlowEventRegister - returs the register based on flow mod type
+// GetFlowEventRegister - returs the register based on flow mod type
 func (d *VoltDevice) GetFlowEventRegister(flowModType of.Command) (*util.ConcurrentMap, error) {
-
 	switch flowModType {
 	case of.CommandDel:
 		return d.FlowDelEventMap, nil
@@ -750,7 +739,7 @@
 	va.IgmpGroupIds = append([]*IgmpGroup{ig}, va.IgmpGroupIds[0:]...)
 }
 
-//RestoreUpgradeStatus - gets upgrade/migration status from DB and updates local flags
+// RestoreUpgradeStatus - gets upgrade/migration status from DB and updates local flags
 func (va *VoltApplication) RestoreUpgradeStatus(cntx context.Context) {
 	Migrate := new(DataMigration)
 	if err := GetMigrationInfo(cntx, Migrate); err == nil {
@@ -792,7 +781,7 @@
 	logger.Info(ctx, "Reconciled from DB")
 }
 
-// InitStaticConfig to initialise static config.
+// InitStaticConfig to initialize static config.
 func (va *VoltApplication) InitStaticConfig() {
 	va.InitIgmpSrcMac()
 }
@@ -949,7 +938,7 @@
 	}
 }
 
-//PortUpdateInd Updates port Id incase of ONU movement
+// PortUpdateInd Updates port Id incase of ONU movement
 func (va *VoltApplication) PortUpdateInd(device string, portName string, id uint32) {
 	logger.Infow(ctx, "Received Port Ind: Update", log.Fields{"Device": device, "Port": portName})
 	va.portLock.Lock()
@@ -965,7 +954,6 @@
 // AddNbPonPort Add pon port to nbDevice
 func (va *VoltApplication) AddNbPonPort(cntx context.Context, oltSbID string, portID, maxAllowedChannels uint32,
 	enableMulticastKPI bool, portAlarmProfileID string) error {
-
 	var nbd *NbDevice
 	nbDevice, ok := va.NbDevice.Load(oltSbID)
 
@@ -996,7 +984,6 @@
 
 // UpdateNbPonPort update pon port to nbDevice
 func (va *VoltApplication) UpdateNbPonPort(cntx context.Context, oltSbID string, portID, maxAllowedChannels uint32, enableMulticastKPI bool, portAlarmProfileID string) error {
-
 	var nbd *NbDevice
 	nbDevice, ok := va.NbDevice.Load(oltSbID)
 
@@ -1078,7 +1065,6 @@
 
 // NniDownInd process for Nni down indication.
 func (va *VoltApplication) NniDownInd(cntx context.Context, deviceID string, devSrNo string) {
-
 	logger.Debugw(ctx, "NNI Down Ind", log.Fields{"device": devSrNo})
 
 	handleIgmpDsFlows := func(key interface{}, value interface{}) bool {
@@ -1124,7 +1110,6 @@
 		d.State = controller.DeviceStateREBOOTED
 	}
 	va.HandleFlowClearFlag(cntx, device, serialNum, southBoundID)
-
 }
 
 // DeviceDisableInd handles device deactivation process
@@ -1143,7 +1128,6 @@
 
 // ProcessIgmpDSFlowForMvlan for processing Igmp DS flow for device
 func (va *VoltApplication) ProcessIgmpDSFlowForMvlan(cntx context.Context, d *VoltDevice, mvp *MvlanProfile, addFlow bool) {
-
 	logger.Debugw(ctx, "Process IGMP DS Flows for MVlan", log.Fields{"device": d.Name, "Mvlan": mvp.Mvlan, "addFlow": addFlow})
 	portState := false
 	p := d.GetPort(d.NniPort)
@@ -1299,13 +1283,12 @@
 	}
 }
 
-//NniVlanIndToIgmp - Trigger receiver up indication to all ports with igmp enabled
-//and has the provided mvlan
+// NniVlanIndToIgmp - Trigger receiver up indication to all ports with igmp enabled
+// and has the provided mvlan
 func (va *VoltApplication) NniVlanIndToIgmp(device *VoltDevice, mvp *MvlanProfile) {
-
 	logger.Infow(ctx, "Sending Igmp Receiver UP indication for all Services", log.Fields{"Vlan": mvp.Mvlan})
 
-	//Trigger nni indication for receiver only for first time
+	// Trigger nni indication for receiver only for first time
 	if device.IgmpDsFlowAppliedForMvlan[uint16(mvp.Mvlan)] {
 		return
 	}
@@ -1318,7 +1301,7 @@
 				return true
 			}
 			for _, vpv := range vpvs.([]*VoltPortVnet) {
-				//Send indication only for subscribers with the received mvlan profile
+				// Send indication only for subscribers with the received mvlan profile
 				if vpv.IgmpEnabled && vpv.MvlanProfileName == mvp.Name {
 					vpv.services.Range(ReceiverUpInd)
 				}
@@ -1343,7 +1326,7 @@
 		return
 	}
 
-	//Fixme: If Port Update Comes in large numbers, this will result in slow update per device
+	// Fixme: If Port Update Comes in large numbers, this will result in slow update per device
 	va.portLock.Lock()
 	// Do not defer the port mutex unlock here
 	// Some of the following func calls needs the port lock, so defering the lock here
@@ -1360,7 +1343,6 @@
 
 	logger.Infow(ctx, "Received SouthBound Port Ind: UP", log.Fields{"Device": device, "PortName": port, "PortId": p.ID})
 	if p.Type == VoltPortTypeNni {
-
 		logger.Warnw(ctx, "Received NNI Port Ind: UP", log.Fields{"Device": device, "PortName": port, "PortId": p.ID})
 		//va.PushDevFlowForDevice(d)
 		//Build Igmp TrapFlowRule
@@ -1373,7 +1355,7 @@
 		return
 	}
 
-	//If NNI port is not UP, do not push Flows
+	// If NNI port is not UP, do not push Flows
 	if d.NniPort == "" {
 		logger.Warnw(ctx, "NNI port not UP. Not sending Port UP Ind for VPVs", log.Fields{"NNI": d.NniPort})
 		return
@@ -1383,7 +1365,7 @@
 	if vpvList[0].PonPort != 0xFF && vpvList[0].PonPort != p.PonPort {
 		logger.Errorw(ctx, "UNI port discovered on wrong PON Port. Dropping Port Indication", log.Fields{"Device": device, "Port": port, "DetectedPon": p.PonPort, "ExpectedPon": vpvList[0].PonPort})
 
-		//Remove the flow (if any) which are already installed - Valid for PON switching when VGC pod is DOWN
+		// Remove the flow (if any) which are already installed - Valid for PON switching when VGC pod is DOWN
 		for _, vpv := range vpvs.([]*VoltPortVnet) {
 			vpv.VpvLock.Lock()
 			logger.Warnw(ctx, "Removing existing VPVs/Services flows for for Subscriber: UNI Detected on wrong PON", log.Fields{"Port": vpv.Port, "Vnet": vpv.VnetName})
@@ -1398,9 +1380,9 @@
 
 	for _, vpv := range vpvs.([]*VoltPortVnet) {
 		vpv.VpvLock.Lock()
-		//If no service is activated drop the portUpInd
+		// If no service is activated drop the portUpInd
 		if vpv.IsServiceActivated(cntx) {
-			//Do not trigger indication for the vpv which is already removed from vpv list as
+			// Do not trigger indication for the vpv which is already removed from vpv list as
 			// part of service delete (during the lock wait duration)
 			// In that case, the services associated wil be zero
 			if vpv.servicesCount.Load() != 0 {
@@ -1435,7 +1417,7 @@
 
 }*/
 
-//ReceiverUpInd - Send receiver up indication for service with Igmp enabled
+// ReceiverUpInd - Send receiver up indication for service with Igmp enabled
 func ReceiverUpInd(key, value interface{}) bool {
 	svc := value.(*VoltService)
 	var vlan of.VlanType
@@ -1445,7 +1427,7 @@
 		return false
 	}
 
-	//Send port up indication to igmp only for service with igmp enabled
+	// Send port up indication to igmp only for service with igmp enabled
 	if svc.IgmpEnabled {
 		if svc.VlanControl == ONUCVlan || svc.VlanControl == ONUCVlanOLTSVlan {
 			vlan = svc.CVlan
@@ -1470,7 +1452,7 @@
 		logger.Warnw(ctx, "Device Not Found - Dropping Port Ind: DOWN", log.Fields{"Device": device, "Port": port})
 		return
 	}
-	//Fixme: If Port Update Comes in large numbers, this will result in slow update per device
+	// Fixme: If Port Update Comes in large numbers, this will result in slow update per device
 	va.portLock.Lock()
 	// Do not defer the port mutex unlock here
 	// Some of the following func calls needs the port lock, so defering the lock here
@@ -1656,7 +1638,7 @@
 		for k := range dev.(*VoltDevice).IgmpDsFlowAppliedForMvlan {
 			delete(dev.(*VoltDevice).IgmpDsFlowAppliedForMvlan, k)
 		}
-		//Delete group 1 - ICMPv6/ARP group
+		// Delete group 1 - ICMPv6/ARP group
 		if err := ProcessIcmpv6McGroup(deviceID, true); err != nil {
 			logger.Errorw(ctx, "ProcessIcmpv6McGroup failed", log.Fields{"Device": deviceID, "Error": err})
 		}
@@ -1676,7 +1658,7 @@
 
 				if vpv.IgmpEnabled {
 					va.ReceiverDownInd(cntx, vpv.Device, vpv.Port)
-					//Also clear service igmp stats
+					// Also clear service igmp stats
 					vpv.ClearServiceCounters(cntx)
 				}
 			}
@@ -1685,15 +1667,15 @@
 	}
 	va.VnetsByPort.Range(getVpvs)
 
-	//Clear Static Group
+	// Clear Static Group
 	va.ReceiverDownInd(cntx, deviceID, StaticPort)
 
 	logger.Warnw(ctx, "All flags cleared for device", log.Fields{"Device": deviceID})
 
-	//Reset pending group pool
+	// Reset pending group pool
 	va.RemovePendingGroups(cntx, deviceID, true)
 
-	//Process all Migrate Service Request - force udpate all profiles since resources are already cleaned up
+	// Process all Migrate Service Request - force udpate all profiles since resources are already cleaned up
 	if dev != nil {
 		triggerForceUpdate := func(key, value interface{}) bool {
 			msrList := value.(*util.ConcurrentMap)
@@ -1711,15 +1693,14 @@
 	}
 }
 
-//GetPonPortIDFromUNIPort to get pon port id from uni port
+// GetPonPortIDFromUNIPort to get pon port id from uni port
 func GetPonPortIDFromUNIPort(uniPortID uint32) uint32 {
 	ponPortID := (uniPortID & 0x0FF00000) >> 20
 	return ponPortID
 }
 
-//ProcessFlowModResultIndication - Processes Flow mod operation indications from controller
+// ProcessFlowModResultIndication - Processes Flow mod operation indications from controller
 func (va *VoltApplication) ProcessFlowModResultIndication(cntx context.Context, flowStatus intf.FlowStatus) {
-
 	d := va.GetDevice(flowStatus.Device)
 	if d == nil {
 		logger.Errorw(ctx, "Dropping Flow Mod Indication. Device not found", log.Fields{"Cookie": flowStatus.Cookie, "Device": flowStatus.Device})
@@ -1743,9 +1724,8 @@
 	logger.Errorw(ctx, "Flow Failure Notification", log.Fields{"uniPort": uniPort, "Cookie": cookie})
 }
 
-//UpdateMvlanProfilesForDevice to update mvlan profile for device
+// UpdateMvlanProfilesForDevice to update mvlan profile for device
 func (va *VoltApplication) UpdateMvlanProfilesForDevice(cntx context.Context, device string) {
-
 	checkAndAddMvlanUpdateTask := func(key, value interface{}) bool {
 		mvp := value.(*MvlanProfile)
 		if mvp.IsUpdateInProgressForDevice(device) {
@@ -1779,16 +1759,13 @@
 
 // UpdateDeviceSerialNumberList to update the device serial number list after device serial number is updated for vnet and mvlan
 func (va *VoltApplication) UpdateDeviceSerialNumberList(oldOltSlNo string, newOltSlNo string) {
-
 	voltDevice, _ := va.GetDeviceBySerialNo(oldOltSlNo)
 
 	if voltDevice != nil {
 		// Device is present with old serial number ID
 		logger.Errorw(ctx, "OLT Migration cannot be completed as there are dangling devices", log.Fields{"Serial Number": oldOltSlNo})
-
 	} else {
 		logger.Infow(ctx, "No device present with old serial number", log.Fields{"Serial Number": oldOltSlNo})
-
 		// Add Serial Number to Blocked Devices List.
 		cntlr.GetController().AddBlockedDevices(oldOltSlNo)
 		cntlr.GetController().AddBlockedDevices(newOltSlNo)
@@ -1824,14 +1801,12 @@
 		// Clear the serial number from Blocked Devices List
 		cntlr.GetController().DelBlockedDevices(oldOltSlNo)
 		cntlr.GetController().DelBlockedDevices(newOltSlNo)
-
 	}
 }
 
 // GetVpvsForDsPkt to get vpv for downstream packets
 func (va *VoltApplication) GetVpvsForDsPkt(cvlan of.VlanType, svlan of.VlanType, clientMAC net.HardwareAddr,
 	pbit uint8) ([]*VoltPortVnet, error) {
-
 	var matchVPVs []*VoltPortVnet
 	findVpv := func(key, value interface{}) bool {
 		vpvs := value.([]*VoltPortVnet)
@@ -1899,7 +1874,7 @@
 	}
 }
 
-//AddGroupToPendingPool - adds the IgmpGroup with active group table entry to global pending pool
+// AddGroupToPendingPool - adds the IgmpGroup with active group table entry to global pending pool
 func (va *VoltApplication) AddGroupToPendingPool(ig *IgmpGroup) {
 	var grpMap map[*IgmpGroup]bool
 	var ok bool
@@ -1925,7 +1900,7 @@
 	}
 }
 
-//RemoveGroupFromPendingPool - removes the group from global pending group pool
+// RemoveGroupFromPendingPool - removes the group from global pending group pool
 func (va *VoltApplication) RemoveGroupFromPendingPool(device string, ig *IgmpGroup) bool {
 	GetApplication().PendingPoolLock.Lock()
 	defer GetApplication().PendingPoolLock.Unlock()
@@ -1940,7 +1915,7 @@
 	return false
 }
 
-//RemoveGroupsFromPendingPool - removes the group from global pending group pool
+// RemoveGroupsFromPendingPool - removes the group from global pending group pool
 func (va *VoltApplication) RemoveGroupsFromPendingPool(cntx context.Context, device string, mvlan of.VlanType) {
 	GetApplication().PendingPoolLock.Lock()
 	defer GetApplication().PendingPoolLock.Unlock()
@@ -1951,7 +1926,7 @@
 	va.RemoveGroupListFromPendingPool(cntx, key)
 }
 
-//RemoveGroupListFromPendingPool - removes the groups for provided key
+// RemoveGroupListFromPendingPool - removes the groups for provided key
 // 1. Deletes the group from device
 // 2. Delete the IgmpGroup obj and release the group ID to pool
 // Note: Make sure to obtain PendingPoolLock lock before calling this func
@@ -1966,18 +1941,16 @@
 	}
 }
 
-//RemoveGroupDevicesFromPendingPool - removes the group from global pending group pool
+// RemoveGroupDevicesFromPendingPool - removes the group from global pending group pool
 func (va *VoltApplication) RemoveGroupDevicesFromPendingPool(ig *IgmpGroup) {
-
 	logger.Infow(ctx, "Removing IgmpGroup for all devices from Global Pending Pool", log.Fields{"GroupID": ig.GroupID, "GroupName": ig.GroupName, "GroupAddr": ig.GroupAddr, "PendingDevices": len(ig.Devices)})
 	for device := range ig.PendingGroupForDevice {
 		va.RemoveGroupFromPendingPool(device, ig)
 	}
 }
 
-//GetGroupFromPendingPool - Returns IgmpGroup obj from global pending pool
+// GetGroupFromPendingPool - Returns IgmpGroup obj from global pending pool
 func (va *VoltApplication) GetGroupFromPendingPool(mvlan of.VlanType, device string) *IgmpGroup {
-
 	var ig *IgmpGroup
 
 	va.PendingPoolLock.Lock()
@@ -1986,43 +1959,42 @@
 	key := getPendingPoolKey(mvlan, device)
 	logger.Infow(ctx, "Getting IgmpGroup from Global Pending Pool", log.Fields{"Device": device, "Mvlan": mvlan.String(), "Key": key})
 
-	//Gets all IgmpGrp Obj for the device
+	// Gets all IgmpGrp Obj for the device
 	grpMap, ok := va.IgmpPendingPool[key]
 	if !ok || len(grpMap) == 0 {
 		logger.Infow(ctx, "Matching IgmpGroup not found in Global Pending Pool", log.Fields{"Device": device, "Mvlan": mvlan.String()})
 		return nil
 	}
 
-	//Gets a random obj from available grps
+	// Gets a random obj from available grps
 	for ig = range grpMap {
-
-		//Remove grp obj reference from all devices associated in pending pool
+		// Remove grp obj reference from all devices associated in pending pool
 		for dev := range ig.Devices {
 			key := getPendingPoolKey(mvlan, dev)
 			delete(va.IgmpPendingPool[key], ig)
 		}
 
-		//Safety check to avoid re-allocating group already in use
+		// Safety check to avoid re-allocating group already in use
 		if ig.NumDevicesActive() == 0 {
 			return ig
 		}
 
-		//Iteration will continue only if IG is not allocated
+		// Iteration will continue only if IG is not allocated
 	}
 	return nil
 }
 
-//RemovePendingGroups - removes all pending groups for provided reference from global pending pool
+// RemovePendingGroups - removes all pending groups for provided reference from global pending pool
 // reference - mvlan/device ID
 // isRefDevice - true  - Device as reference
-//               false - Mvlan as reference
+// false - Mvlan as reference
 func (va *VoltApplication) RemovePendingGroups(cntx context.Context, reference string, isRefDevice bool) {
 	va.PendingPoolLock.Lock()
 	defer va.PendingPoolLock.Unlock()
 
 	logger.Infow(ctx, "Removing IgmpGroups from Global Pending Pool", log.Fields{"Reference": reference, "isRefDevice": isRefDevice})
 
-	//Pending Pool key: "<mvlan>_<DeviceID>""
+	// Pending Pool key: "<mvlan>_<DeviceID>""
 	paramPosition := 0
 	if isRefDevice {
 		paramPosition = 1
@@ -2053,7 +2025,7 @@
 	va.IgmpGroups.Range(removeExpiredGroups)
 }
 
-//TriggerPendingProfileDeleteReq - trigger pending profile delete request
+// TriggerPendingProfileDeleteReq - trigger pending profile delete request
 func (va *VoltApplication) TriggerPendingProfileDeleteReq(cntx context.Context, device string) {
 	va.TriggerPendingServiceDeleteReq(cntx, device)
 	va.TriggerPendingVpvDeleteReq(cntx, device)
@@ -2061,9 +2033,8 @@
 	logger.Warnw(ctx, "All Pending Profile Delete triggered for device", log.Fields{"Device": device})
 }
 
-//TriggerPendingServiceDeleteReq - trigger pending service delete request
+// TriggerPendingServiceDeleteReq - trigger pending service delete request
 func (va *VoltApplication) TriggerPendingServiceDeleteReq(cntx context.Context, device string) {
-
 	logger.Warnw(ctx, "Pending Services to be deleted", log.Fields{"Count": len(va.ServicesToDelete)})
 	for serviceName := range va.ServicesToDelete {
 		logger.Debugw(ctx, "Trigger Service Delete", log.Fields{"Service": serviceName})
@@ -2081,9 +2052,8 @@
 	}
 }
 
-//TriggerPendingVpvDeleteReq - trigger pending VPV delete request
+// TriggerPendingVpvDeleteReq - trigger pending VPV delete request
 func (va *VoltApplication) TriggerPendingVpvDeleteReq(cntx context.Context, device string) {
-
 	logger.Warnw(ctx, "Pending VPVs to be deleted", log.Fields{"Count": len(va.VoltPortVnetsToDelete)})
 	for vpv := range va.VoltPortVnetsToDelete {
 		if vpv.Device == device {
@@ -2093,9 +2063,8 @@
 	}
 }
 
-//TriggerPendingVnetDeleteReq - trigger pending vnet delete request
+// TriggerPendingVnetDeleteReq - trigger pending vnet delete request
 func (va *VoltApplication) TriggerPendingVnetDeleteReq(cntx context.Context, device string) {
-
 	logger.Warnw(ctx, "Pending Vnets to be deleted", log.Fields{"Count": len(va.VnetsToDelete)})
 	for vnetName := range va.VnetsToDelete {
 		if vnetIntf, _ := va.VnetsByName.Load(vnetName); vnetIntf != nil {
@@ -2112,8 +2081,8 @@
 }
 
 type OltFlowService struct {
+	DefaultTechProfileID int  `json:"defaultTechProfileId"`
 	EnableDhcpOnNni      bool `json:"enableDhcpOnNni"`
-	DefaultTechProfileId int  `json:"defaultTechProfileId"`
 	EnableIgmpOnNni      bool `json:"enableIgmpOnNni"`
 	EnableEapol          bool `json:"enableEapol"`
 	EnableDhcpV6         bool `json:"enableDhcpV6"`
diff --git a/internal/pkg/application/dhcprelay.go b/internal/pkg/application/dhcprelay.go
index e32a7d0..346bd3d 100644
--- a/internal/pkg/application/dhcprelay.go
+++ b/internal/pkg/application/dhcprelay.go
@@ -107,11 +107,11 @@
 // to the network. It supports two VLANs as its identify. If a single VLAN or
 // no VLAN is to be used, those two should be passed as 4096 (VlanNone)
 type DhcpRelayVnet struct {
-	OuterVlan   uint16
-	InnerVlan   uint16
 	sessions    map[[6]byte]IDhcpRelaySession
 	sessionsv6  map[[MaxLenDhcpv6DUID]byte]IDhcpRelaySession
 	sessionLock sync.RWMutex
+	OuterVlan   uint16
+	InnerVlan   uint16
 }
 
 // DhcpNetworks hosts different DHCP networks that in turn hold the DHCP
@@ -270,7 +270,6 @@
 
 // GetVlansFromPacket to get vlans from the packet
 func GetVlansFromPacket(pkt gopacket.Packet) (innerVlan of.VlanType, outerVlan of.VlanType) {
-
 	vlans := GetVlans(pkt)
 	if len(vlans) == 1 {
 		outerVlan = vlans[0]
@@ -375,7 +374,6 @@
 
 // getDhcpv6ClientDUID to get Dhcpv6 client DUID
 func getDhcpv6ClientDUID(dhcpv6 *layers.DHCPv6) ([]byte, *layers.DHCPv6DUID) {
-
 	for _, option := range dhcpv6.Options {
 		logger.Debugw(ctx, "DHCPv6 Options", log.Fields{"option": option.Code})
 		if option.Code == layers.DHCPv6OptClientID {
@@ -475,7 +473,7 @@
 	return dhcp.YourClientIP, int64(leaseTime)
 }
 
-//GetIPv4LeaseTime get ip lease time
+// GetIPv4LeaseTime get ip lease time
 func GetIPv4LeaseTime(opt layers.DHCPOption) uint32 {
 	return uint32(opt.Data[0])<<24 | uint32(opt.Data[1])<<16 | uint32(opt.Data[2])<<8 | uint32(opt.Data[3])
 }
@@ -502,7 +500,6 @@
 	if dhcp6.MsgType == layers.DHCPv6MsgTypeReply {
 		for _, o := range dhcp6.Options {
 			if o.Code == layers.DHCPv6OptIANA {
-
 				iana := &layers.DHCPv6IANA{}
 				err := iana.DecodeFromBytes(o.Data)
 				if err == nil {
@@ -526,7 +523,6 @@
 	if dhcp6.MsgType == layers.DHCPv6MsgTypeReply {
 		for _, o := range dhcp6.Options {
 			if o.Code == layers.DHCPv6OptIAPD {
-
 				iapd := &layers.DHCPv6IAPD{}
 				if err := iapd.DecodeFromBytes(o.Data); err == nil {
 					ipv6Addr = iapd.PD.Prefix
@@ -550,7 +546,6 @@
 // common map. The key for retrieval includes the VLAN tags in the
 // the packet and the MAC address of the client.
 func (va *VoltApplication) ProcessDsDhcpv4Packet(cntx context.Context, device string, port string, pkt gopacket.Packet) {
-
 	// Retrieve the layers to build the outgoing packet. It is not
 	// possible to add/remove layers to the existing packet and thus
 	// the lyayers are extracted to build the outgoing packet
@@ -605,7 +600,6 @@
 					go vpv.SetMacAddr(cntx, dhcp4.ClientHWAddr)
 				}
 				vpv.DhcpResultInd(cntx, dhcp4)
-
 			}
 			raiseDHCPv4Indication(msgType, vpv, dhcp4.ClientHWAddr, ipAddr, dsPbit, device, leaseTime)
 		}
@@ -687,7 +681,6 @@
 // raiseDHCPv4Indication process DHCPv4 packet and raise indication
 func raiseDHCPv4Indication(msgType layers.DHCPMsgType, vpv *VoltPortVnet, smac net.HardwareAddr,
 	ip net.IP, pktPbit uint8, device string, leaseTime int64) {
-
 	logger.Debugw(ctx, "Processing Dhcpv4 packet", log.Fields{"ethsrcMac": smac.String(),
 		"MacLearningInVPV": vpv.MacLearning, "MacConfigured": vpv.MacAddr, "dhcpType": msgType,
 		"vlanPriority": pktPbit, "VPVLearntMac": vpv.LearntMacAddr})
@@ -731,7 +724,6 @@
 // raiseDHCPv6Indication process DHCPv6 packet and raise indication
 func raiseDHCPv6Indication(msgType layers.DHCPv6MsgType, vpv *VoltPortVnet,
 	smac net.HardwareAddr, ip net.IP, pktPbit uint8, device string, leaseTime uint32) {
-
 	logger.Debugw(ctx, "Processing DHCPv6 packet", log.Fields{"dhcpType": msgType,
 		"vlanPriority": pktPbit, "dhcpClientMac": smac.String(),
 		"MacLearningInVPV": vpv.MacLearning, "MacConfigured": vpv.MacAddr,
@@ -933,7 +925,7 @@
 // We determine the packet direction and process it based on the direction
 func (va *VoltApplication) ProcessUDP4Packet(cntx context.Context, device string, port string, pkt gopacket.Packet) {
 	// Currently DHCP is the only application supported by the application
-	// We check for DHCP before proceeding futher. In future, this could be
+	// We check for DHCP before proceeding further. In future, this could be
 	// based on registration and the callbacks
 	dhcpl := pkt.Layer(layers.LayerTypeDHCPv4)
 	if dhcpl == nil {
@@ -950,7 +942,6 @@
 		// This is a downstream packet
 		va.ProcessDsDhcpv4Packet(cntx, device, port, pkt)
 	}
-
 }
 
 // ProcessUDP6Packet : CallBack function registered with application to handle DHCPv6 packetIn
@@ -1018,6 +1009,7 @@
 	return dhcp6
 }
 
+// nolint: gocyclo
 // ProcessUsDhcpv6Packet to rpocess upstream DHCPv6 packet
 func (va *VoltApplication) ProcessUsDhcpv6Packet(cntx context.Context, device string, port string, pkt gopacket.Packet) {
 	// We received the packet on an access port and the service for the packet can be
@@ -1144,7 +1136,6 @@
 			qdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: vlan, DropEligible: dropEligible, Type: nxtLayer}
 			qVlanLayers = append(qVlanLayers, qdot1q)
 		}
-
 	}
 	switch vpv.VlanControl {
 	case ONUCVlanOLTSVlan,
@@ -1240,7 +1231,6 @@
 	ipv6Addr, leaseTime := GetIpv6Addr(dhcp6)
 
 	for _, vpv := range vpvList {
-
 		dsPbit = vpv.GetRemarkedPriority(priority)
 		// Raise DHCPv6 Reply indication
 		if vpv.DhcpRelay {
@@ -1303,7 +1293,6 @@
 				qdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: vlan, DropEligible: dropEligible, Type: nxtLayer}
 				qVlanLayers = append(qVlanLayers, qdot1q)
 			}
-
 		}
 		switch vpv.VlanControl {
 		case ONUCVlanOLTSVlan:
@@ -1347,12 +1336,12 @@
 type DhcpAllocation struct {
 	SubscriberID        string           `json:"subscriberId"`
 	ConnectPoint        string           `json:"connectPoint"`
+	AllocationTimeStamp time.Time        `json:"allocationTimestamp"`
 	MacAddress          net.HardwareAddr `json:"macAddress"`
+	CircuitID           []byte           `json:"circuitId"`
+	IPAllocated         net.IP           `json:"ipAllocated"`
 	State               int              `json:"state"`
 	VlanID              int              `json:"vlanId"`
-	CircuitID           []byte           `json:"circuitId"`
-	IpAllocated         net.IP           `json:"ipAllocated"`
-	AllocationTimeStamp time.Time        `json:"allocationTimestamp"`
 }
 
 // GetAllocations returns DhcpAllocation info for all devices or for a device ID
@@ -1381,7 +1370,7 @@
 						State:               int(vpv.RelayState),
 						VlanID:              int(vpv.SVlan),
 						CircuitID:           vpv.CircuitID,
-						IpAllocated:         vpv.Ipv4Addr,
+						IPAllocated:         vpv.Ipv4Addr,
 						AllocationTimeStamp: vpv.DhcpExpiryTime,
 					}
 					logger.Debugw(ctx, "DHCP Allocation found", log.Fields{"DhcpAlloc": allocation})
@@ -1395,9 +1384,9 @@
 }
 
 type MacLearnerInfo struct {
-	DeviceId   string `json:"deviceId"`
+	DeviceID   string `json:"deviceId"`
 	PortNumber string `json:"portNumber"`
-	VlanId     string `json:"vlanId"`
+	VlanID     string `json:"vlanId"`
 	MacAddress string `json:"macAddress"`
 }
 
@@ -1411,9 +1400,9 @@
 			vpv, ok := session.(*VoltPortVnet)
 			if ok {
 				macLearn := MacLearnerInfo{
-					DeviceId:   vpv.Device,
+					DeviceID:   vpv.Device,
 					PortNumber: vpv.Port,
-					VlanId:     vpv.SVlan.String(),
+					VlanID:     vpv.SVlan.String(),
 					MacAddress: vpv.MacAddr.String(),
 				}
 				logger.Debugw(ctx, "MacLerner found", log.Fields{"MacLearn": macLearn})
@@ -1425,7 +1414,7 @@
 	return macLearner, nil
 }
 
-func (va *VoltApplication) GetMacLearnerInfo(cntx context.Context, deviceId, portNumber, vlanId string) (MacLearnerInfo, error) {
+func (va *VoltApplication) GetMacLearnerInfo(cntx context.Context, deviceID, portNumber, vlanID string) (MacLearnerInfo, error) {
 	logger.Info(ctx, "GetMecLearnerInfo")
 	macLearn := MacLearnerInfo{}
 	for _, drv := range dhcpNws.Networks {
@@ -1434,19 +1423,19 @@
 		for _, session := range drv.sessions {
 			vpv, ok := session.(*VoltPortVnet)
 			if ok {
-				if deviceId == vpv.Device && portNumber == vpv.Port && vlanId == vpv.SVlan.String() {
+				if deviceID == vpv.Device && portNumber == vpv.Port && vlanID == vpv.SVlan.String() {
 					macLearn = MacLearnerInfo{
-						DeviceId:   vpv.Device,
+						DeviceID:   vpv.Device,
 						PortNumber: vpv.Port,
-						VlanId:     vpv.SVlan.String(),
+						VlanID:     vpv.SVlan.String(),
 						MacAddress: vpv.MacAddr.String(),
 					}
 					logger.Infow(ctx, "MacLerner found", log.Fields{"MacLearn": macLearn})
-				} else if deviceId == vpv.Device && portNumber == vpv.Port && vlanId == "" {
+				} else if deviceID == vpv.Device && portNumber == vpv.Port && vlanID == "" {
 					macLearn = MacLearnerInfo{
-						DeviceId:   vpv.Device,
+						DeviceID:   vpv.Device,
 						PortNumber: vpv.Port,
-						VlanId:     vpv.SVlan.String(),
+						VlanID:     vpv.SVlan.String(),
 						MacAddress: vpv.MacAddr.String(),
 					}
 					logger.Infow(ctx, "MacLerner found", log.Fields{"MacLearn": macLearn})
@@ -1473,7 +1462,6 @@
 				return true
 			}
 			for _, vpv := range vnets.([]*VoltPortVnet) {
-
 				if vpv.MacLearning == MacLearningNone {
 					IgnoredPorts[vpv.Device] = append(IgnoredPorts[vpv.Device], vpv.Port)
 				}
diff --git a/internal/pkg/application/dhcpserverhandler.go b/internal/pkg/application/dhcpserverhandler.go
index 947dd34..44cdb8e 100644
--- a/internal/pkg/application/dhcpserverhandler.go
+++ b/internal/pkg/application/dhcpserverhandler.go
@@ -40,7 +40,7 @@
 
 // StartDhcpServerHandler starts go routine periodically(every second) to verify DHCP server reachability.
 func StartDhcpServerHandler() {
-	// Intialize global dhcp map and ticker as one second
+	// Initialize global dhcp map and ticker as one second
 	dhcpServerInfo = make(map[dhcpServerTag]dhcpTransactionInfo)
 	ticker := time.NewTicker(1 * time.Second)
 
@@ -55,7 +55,6 @@
 				mux.Lock()
 				checkDhcpTimeout()
 				mux.Unlock()
-
 			}
 		}
 	}()
@@ -168,11 +167,11 @@
 
 // dhcpTransactionInfo contains DHCP request response transaction information.
 type dhcpTransactionInfo struct {
-	timer                 uint8
+	smac                  string
 	pendingRequestCount   uint32
 	receivedResponseCount uint32
 	previousRequestCount  uint32
-	smac                  string
+	timer                 uint8
 }
 
 func newDhcpTransactionInfo(timer uint8, smac string) dhcpTransactionInfo {
diff --git a/internal/pkg/application/flowevent.go b/internal/pkg/application/flowevent.go
index fe37b74..be52fbb 100644
--- a/internal/pkg/application/flowevent.go
+++ b/internal/pkg/application/flowevent.go
@@ -24,45 +24,45 @@
 	"voltha-go-controller/log"
 )
 
-//Generic Framework to enabling all flow based event trigger and handling.
-//The eventMapper can be updated for dynamic func caller for future events
+// Generic Framework to enabling all flow based event trigger and handling.
+// The eventMapper can be updated for dynamic func caller for future events
 
-//FlowEventType - Type of event enumeration
+// FlowEventType - Type of event enumeration
 type FlowEventType string
 
-//FlowEventHandler - Func prototype for flow event handling funcs
+// FlowEventHandler - Func prototype for flow event handling funcs
 type FlowEventHandler func(context.Context, *FlowEvent, intf.FlowStatus)
 
 var eventMapper map[FlowEventType]FlowEventHandler
 
 const (
-	//EventTypeUsIgmpFlowAdded - Event type for IGMP US flow add
+	// EventTypeUsIgmpFlowAdded - Event type for IGMP US flow add
 	EventTypeUsIgmpFlowAdded FlowEventType = "USIgmpFlowAdded"
-	//EventTypeServiceFlowAdded - Event type for Service flow add
+	// EventTypeServiceFlowAdded - Event type for Service flow add
 	EventTypeServiceFlowAdded FlowEventType = "ServiceFlowAdded"
-	//EventTypeControlFlowAdded - Event type for Control flow add
+	// EventTypeControlFlowAdded - Event type for Control flow add
 	EventTypeControlFlowAdded FlowEventType = "ControlFlowAdded"
 
-	//EventTypeDeviceFlowRemoved - Event type for Device flow del
+	// EventTypeDeviceFlowRemoved - Event type for Device flow del
 	EventTypeDeviceFlowRemoved FlowEventType = "DeviceFlowRemoved"
-	//EventTypeMcastFlowRemoved - Event type for Mcast flow del
+	// EventTypeMcastFlowRemoved - Event type for Mcast flow del
 	EventTypeMcastFlowRemoved FlowEventType = "McastFlowRemoved"
 
-	//EventTypeServiceFlowRemoved - Event type for Service flow del
+	// EventTypeServiceFlowRemoved - Event type for Service flow del
 	EventTypeServiceFlowRemoved FlowEventType = "ServiceFlowRemoved"
-	//EventTypeControlFlowRemoved - Event type for Control flow del
+	// EventTypeControlFlowRemoved - Event type for Control flow del
 	EventTypeControlFlowRemoved FlowEventType = "ControlFlowRemoved"
 )
 
-//FlowEvent - Event info for Flow event processing
+// FlowEvent - Event info for Flow event processing
 type FlowEvent struct {
-	eType     FlowEventType
+	eventData interface{}
 	device    string
 	cookie    string
-	eventData interface{}
+	eType     FlowEventType
 }
 
-//InitEventFuncMapper - Initialization of flow event mapper
+// InitEventFuncMapper - Initialization of flow event mapper
 func InitEventFuncMapper() {
 	eventMapper = map[FlowEventType]FlowEventHandler{
 		EventTypeUsIgmpFlowAdded:    ProcessUsIgmpFlowAddEvent,
@@ -75,7 +75,7 @@
 	}
 }
 
-//ExecuteFlowEvent - Process flow based event triggers
+// ExecuteFlowEvent - Process flow based event triggers
 func ExecuteFlowEvent(cntx context.Context, vd *VoltDevice, cookie string, flowStatus intf.FlowStatus) bool {
 	var event interface{}
 
@@ -98,9 +98,8 @@
 	return true
 }
 
-//ProcessUsIgmpFlowAddEvent - Process Us Igmp Flow event trigger
+// ProcessUsIgmpFlowAddEvent - Process Us Igmp Flow event trigger
 func ProcessUsIgmpFlowAddEvent(cntx context.Context, event *FlowEvent, flowStatus intf.FlowStatus) {
-
 	logger.Infow(ctx, "Processing Post Flow Add Event for US Igmp", log.Fields{"Cookie": event.cookie, "event": event})
 	vpv := event.eventData.(*VoltPortVnet)
 	if isFlowStatusSuccess(flowStatus.Status, true) {
@@ -110,9 +109,8 @@
 	}
 }
 
-//ProcessServiceFlowAddEvent - Process Service Flow event trigger
+// ProcessServiceFlowAddEvent - Process Service Flow event trigger
 func ProcessServiceFlowAddEvent(cntx context.Context, event *FlowEvent, flowStatus intf.FlowStatus) {
-
 	logger.Infow(ctx, "Processing Post Flow Add Event for Service", log.Fields{"Cookie": event.cookie, "event": event})
 	vs := event.eventData.(*VoltService)
 	if isFlowStatusSuccess(flowStatus.Status, true) {
@@ -122,9 +120,8 @@
 	}
 }
 
-//ProcessControlFlowAddEvent - Process Control Flow event trigger
+// ProcessControlFlowAddEvent - Process Control Flow event trigger
 func ProcessControlFlowAddEvent(cntx context.Context, event *FlowEvent, flowStatus intf.FlowStatus) {
-
 	logger.Infow(ctx, "Processing Post Flow Add Event for VPV", log.Fields{"Cookie": event.cookie, "event": event})
 	vpv := event.eventData.(*VoltPortVnet)
 	if !isFlowStatusSuccess(flowStatus.Status, true) {
@@ -132,9 +129,8 @@
 	}
 }
 
-//ProcessServiceFlowDelEvent - Process Service Flow event trigger
+// ProcessServiceFlowDelEvent - Process Service Flow event trigger
 func ProcessServiceFlowDelEvent(cntx context.Context, event *FlowEvent, flowStatus intf.FlowStatus) {
-
 	logger.Infow(ctx, "Processing Post Flow Remove Event for Service", log.Fields{"Cookie": event.cookie, "event": event})
 	vs := event.eventData.(*VoltService)
 	if isFlowStatusSuccess(flowStatus.Status, false) {
@@ -144,9 +140,8 @@
 	}
 }
 
-//ProcessControlFlowDelEvent - Process Control Flow event trigger
+// ProcessControlFlowDelEvent - Process Control Flow event trigger
 func ProcessControlFlowDelEvent(cntx context.Context, event *FlowEvent, flowStatus intf.FlowStatus) {
-
 	logger.Infow(ctx, "Processing Post Flow Remove Event for VPV", log.Fields{"Cookie": event.cookie, "event": event})
 	vpv := event.eventData.(*VoltPortVnet)
 	if isFlowStatusSuccess(flowStatus.Status, false) {
@@ -156,9 +151,8 @@
 	}
 }
 
-//ProcessMcastFlowDelEvent - Process Control Flow event trigger
+// ProcessMcastFlowDelEvent - Process Control Flow event trigger
 func ProcessMcastFlowDelEvent(cntx context.Context, event *FlowEvent, flowStatus intf.FlowStatus) {
-
 	logger.Infow(ctx, "Processing Post Flow Remove Event for Mcast/Igmp", log.Fields{"Cookie": event.cookie, "event": event})
 	mvp := event.eventData.(*MvlanProfile)
 	if isFlowStatusSuccess(flowStatus.Status, false) {
@@ -168,9 +162,8 @@
 	}
 }
 
-//ProcessDeviceFlowDelEvent - Process Control Flow event trigger
+// ProcessDeviceFlowDelEvent - Process Control Flow event trigger
 func ProcessDeviceFlowDelEvent(cntx context.Context, event *FlowEvent, flowStatus intf.FlowStatus) {
-
 	logger.Infow(ctx, "Processing Post Flow Remove Event for VNET", log.Fields{"Cookie": event.cookie, "event": event})
 	vnet := event.eventData.(*VoltVnet)
 	if isFlowStatusSuccess(flowStatus.Status, false) {
@@ -180,7 +173,7 @@
 	}
 }
 
-//TODO: Update the func or flowStatus struct once all flow status are based on NB error code
+// TODO: Update the func or flowStatus struct once all flow status are based on NB error code
 func isFlowStatusSuccess(status uint32, flowAdd bool) bool {
 	result := false
 	errorCode := infraerrorcode.ErrorCode(status)
diff --git a/internal/pkg/application/igmp.go b/internal/pkg/application/igmp.go
index 91afdf8..a531619 100644
--- a/internal/pkg/application/igmp.go
+++ b/internal/pkg/application/igmp.go
@@ -86,11 +86,11 @@
 	OltSerialNum   string
 	MvlanProfileID string
 	IgmpProfileID  string
-	IgmpProxyIP    net.IP
-	OperState      OperInProgress
 	Version        string
 	// This map will help in updating the igds whenever there is a igmp profile id update
 	IgmpGroupDevices sync.Map `json:"-"` // Key is group id
+	IgmpProxyIP      net.IP
+	OperState        OperInProgress
 }
 
 var (
@@ -144,7 +144,6 @@
 				}
 			}
 		}
-
 	}
 	return "", errors.New("MAC Address not found,Setting default")
 }
@@ -420,9 +419,8 @@
 	return false
 }
 
-//AddToPendingPool - adds Igmp Device obj to pending pool
+// AddToPendingPool - adds Igmp Device obj to pending pool
 func AddToPendingPool(cntx context.Context, device string, groupKey string) bool {
-
 	logger.Infow(ctx, "Add Device to IgmpGroup Pending Pool", log.Fields{"Device": device, "GroupKey": groupKey})
 	if grp, ok := GetApplication().IgmpGroups.Load(groupKey); ok {
 		ig := grp.(*IgmpGroup)
@@ -450,7 +448,6 @@
 
 // SendQueryExpiredEventGroupSpecific to send group specific query expired event.
 func SendQueryExpiredEventGroupSpecific(portKey string, igd *IgmpGroupDevice, igc *IgmpGroupChannel) {
-
 	logger.Info(ctx, "Processing-SendQueryExpiredEventGroupSpecific-Event")
 	va := GetApplication()
 	mvpName := va.GetMvlanProfileByTag(igd.Mvlan).Name
@@ -476,7 +473,6 @@
 
 // GetMcastServiceForSubAlarm to get mcast service name for subscriber alarm.
 func GetMcastServiceForSubAlarm(uniPort *VoltPort, mvp *MvlanProfile) string {
-
 	var serviceName string
 	mvpName := mvp.Name
 
@@ -501,12 +497,10 @@
 	}
 
 	return serviceName
-
 }
 
 // RestoreIgmpGroupsFromDb to restore igmp groups from database
 func (va *VoltApplication) RestoreIgmpGroupsFromDb(cntx context.Context) {
-
 	groups, _ := db.GetIgmpGroups(cntx)
 	for _, group := range groups {
 		b, ok := group.Value.([]byte)
@@ -546,7 +540,6 @@
 // for the IGMP group and grp obj is obtained from the available pending pool of groups.
 // If not, new group obj will be created based on available group IDs
 func (va *VoltApplication) AddIgmpGroup(cntx context.Context, mvpName string, gip net.IP, device string) *IgmpGroup {
-
 	var ig *IgmpGroup
 	if mvp, grpName := va.GetMvlanProfileForMcIP(mvpName, gip); mvp != nil {
 		if ig = va.GetGroupFromPendingPool(mvp.Mvlan, device); ig != nil {
@@ -580,7 +573,6 @@
 // we have to take a relook at this implementation. The key will include
 // both MVLAN and the group IP.
 func (va *VoltApplication) GetIgmpGroup(mvlan of.VlanType, gip net.IP) *IgmpGroup {
-
 	profile, _ := va.MvlanProfilesByTag.Load(mvlan)
 	if profile == nil {
 		logger.Errorw(ctx, "Mvlan Profile not found for incoming packet. Dropping Request", log.Fields{"Mvlan": mvlan, "GroupAddr": gip.String()})
@@ -608,7 +600,6 @@
 // DelIgmpGroup : When the last subscriber leaves the IGMP group across all the devices
 // the IGMP group is removed.
 func (va *VoltApplication) DelIgmpGroup(cntx context.Context, ig *IgmpGroup) {
-
 	profile, found := GetApplication().MvlanProfilesByTag.Load(ig.Mvlan)
 	if found {
 		mvp := profile.(*MvlanProfile)
@@ -632,13 +623,11 @@
 			}
 			ig.IgmpGroupLock.Unlock()
 		}
-
 	}
 }
 
 // GetPonPortID Gets the PON port ID from uniPortID
 func (va *VoltApplication) GetPonPortID(device, uniPortID string) uint32 {
-
 	isNNI := strings.Contains(uniPortID, "nni")
 	if isNNI || uniPortID == StaticPort {
 		logger.Debugw(ctx, "Cannot get pon port from UNI port", log.Fields{"port": uniPortID})
@@ -685,7 +674,6 @@
 // AggActiveChannelsCountForPonPort Aggregates the active channel count for given pon port.
 // It will iterate over all the groups and store the sum of active channels in VoltDevice.
 func (va *VoltApplication) AggActiveChannelsCountForPonPort(device string, ponPortID uint32, port *PonPortCfg) {
-
 	var activeChannelCount uint32
 
 	collectActiveChannelCount := func(key interface{}, value interface{}) bool {
@@ -744,7 +732,6 @@
 // channel per pon threshold. If Exceeds, return true else return false.
 func (va *VoltApplication) IsMaxChannelsCountExceeded(device, uniPortID string,
 	ponPortID uint32, ig *IgmpGroup, channelIP net.IP, mvp *MvlanProfile) bool {
-
 	// New receiver check is required to identify the IgmpReportMsg received
 	// in response to the IGMP Query sent from VGC.
 	if newReceiver := ig.IsNewReceiver(device, uniPortID, channelIP); !newReceiver {
@@ -821,7 +808,6 @@
 	logger.Debugw(ctx, "Received IGMPv2 Type", log.Fields{"Type": igmpv2.Type})
 
 	if igmpv2.Type == layers.IGMPMembershipReportV2 || igmpv2.Type == layers.IGMPMembershipReportV1 {
-
 		logger.Infow(ctx, "IGMP Join received: v2", log.Fields{"Addr": igmpv2.GroupAddress, "Port": port})
 
 		// This is a report coming from the PON. We must be able to first find the
@@ -897,7 +883,6 @@
 		// This is a IGMP leave coming from one of the receivers. We essentially remove the
 		// the receiver.
 		logger.Infow(ctx, "IGMP Leave received: v2", log.Fields{"Addr": igmpv2.GroupAddress, "Port": port})
-
 		vpv, _ = va.GetVnetFromPkt(device, port, pkt)
 		if vpv == nil {
 			logger.Errorw(ctx, "Couldn't find VNET associated with port", log.Fields{"Port": port})
@@ -993,8 +978,7 @@
 		defer mvp.mvpLock.RUnlock()
 		mvlan := mvp.Mvlan
 
-		for _, group := range igmpv3.GroupRecords {
-
+		for i, group := range igmpv3.GroupRecords {
 			isJoin := isIgmpJoin(group.Type, group.SourceAddresses)
 			// The subscriber is validated and now process the IGMP report
 			ig := va.GetIgmpGroup(mvlan, group.MulticastAddress)
@@ -1019,13 +1003,13 @@
 						ig.IgmpGroupLock.Unlock()
 						return
 					}
-					ig.AddReceiver(cntx, device, port, group.MulticastAddress, &group, IgmpVersion3,
+					ig.AddReceiver(cntx, device, port, group.MulticastAddress, &igmpv3.GroupRecords[i], IgmpVersion3,
 						dot1Q.VLANIdentifier, dot1Q.Priority, ponPortID)
 					ig.IgmpGroupLock.Unlock()
 				} else {
 					// Create the IGMP group and then add the receiver to the group
 					logger.Infow(ctx, "IGMP Join received for new group", log.Fields{"Addr": group.MulticastAddress, "Port": port})
-					if ig := va.AddIgmpGroup(cntx, vpv.MvlanProfileName, group.MulticastAddress, device); ig != nil {
+					if ig = va.AddIgmpGroup(cntx, vpv.MvlanProfileName, group.MulticastAddress, device); ig != nil {
 						ig.IgmpGroupLock.Lock()
 						// Check for port state to avoid race condition where PortDown event
 						// acquired lock before packet processing
@@ -1037,7 +1021,7 @@
 							ig.IgmpGroupLock.Unlock()
 							return
 						}
-						ig.AddReceiver(cntx, device, port, group.MulticastAddress, &group, IgmpVersion3,
+						ig.AddReceiver(cntx, device, port, group.MulticastAddress, &igmpv3.GroupRecords[i], IgmpVersion3,
 							dot1Q.VLANIdentifier, dot1Q.Priority, ponPortID)
 						ig.IgmpGroupLock.Unlock()
 					} else {
@@ -1047,7 +1031,7 @@
 			} else if ig != nil {
 				logger.Infow(ctx, "IGMP Leave received for existing group", log.Fields{"Addr": group.MulticastAddress, "Port": port})
 				ig.IgmpGroupLock.Lock()
-				ig.DelReceiver(cntx, device, port, group.MulticastAddress, &group, ponPortID)
+				ig.DelReceiver(cntx, device, port, group.MulticastAddress, &igmpv3.GroupRecords[i], ponPortID)
 				ig.IgmpGroupLock.Unlock()
 				if ig.NumDevicesActive() == 0 {
 					va.DelIgmpGroup(cntx, ig)
@@ -1135,7 +1119,6 @@
 }
 
 func isIncl(recordType layers.IGMPv3GroupRecordType) bool {
-
 	if (layers.IGMPToIn == recordType) || (layers.IGMPIsIn == recordType) || (layers.IGMPAllow == recordType) {
 		return true
 	}
@@ -1223,9 +1206,8 @@
 	return nil
 }
 
-//UpdateMvlanProfile - only channel groups be updated
+// UpdateMvlanProfile - only channel groups be updated
 func (va *VoltApplication) UpdateMvlanProfile(cntx context.Context, name string, vlan of.VlanType, groups map[string][]string, activeChannelCount int, proxy map[string]common.MulticastGroupProxy) error {
-
 	mvpIntf, ok := va.MvlanProfilesByName.Load(name)
 	if !ok {
 		logger.Error(ctx, "Update Mvlan Failed: Profile does not exist")
@@ -1398,7 +1380,7 @@
 	var mvp *MvlanProfile
 	if mvpIntf, ok := va.MvlanProfilesByName.Load(MvlanProfileID); ok {
 		mvp = mvpIntf.(*MvlanProfile)
-		//Delete from mvp list
+		// Delete from mvp list
 		mvp.removeIgmpMcastFlows(cntx, OltSerialNum)
 		delete(mvp.DevicesList, OltSerialNum)
 		if err := mvp.WriteToDb(cntx); err != nil {
@@ -1409,7 +1391,6 @@
 
 // DelMcastConfig for addition of a MVLAN profile
 func (va *VoltApplication) DelMcastConfig(cntx context.Context, MvlanProfileID string, IgmpProfileID string, IgmpProxyIP string, OltSerialNum string) {
-
 	va.delOltFromMvlan(cntx, MvlanProfileID, OltSerialNum)
 	va.deleteMcastConfig(OltSerialNum, MvlanProfileID)
 	_ = db.DelMcastConfig(cntx, McastConfigKey(OltSerialNum, MvlanProfileID))
@@ -1422,7 +1403,6 @@
 
 // DelAllMcastConfig for deletion of all mcast config
 func (va *VoltApplication) DelAllMcastConfig(cntx context.Context, OltSerialNum string) error {
-
 	deleteIndividualMcastConfig := func(key interface{}, value interface{}) bool {
 		mcastCfg := value.(*McastConfig)
 		if mcastCfg.OltSerialNum == OltSerialNum {
@@ -1436,7 +1416,6 @@
 
 // UpdateMcastConfig for addition of a MVLAN profile
 func (va *VoltApplication) UpdateMcastConfig(cntx context.Context, MvlanProfileID string, IgmpProfileID string, IgmpProxyIP string, OltSerialNum string) error {
-
 	mcastCfg := va.GetMcastConfig(OltSerialNum, MvlanProfileID)
 	if mcastCfg == nil {
 		logger.Warnw(ctx, "Mcast Config not found. Unable to update", log.Fields{"Mvlan Profile ID": MvlanProfileID, "OltSerialNum": OltSerialNum})
@@ -1600,7 +1579,7 @@
 	// va.IgmpTick()
 }
 
-//AddIgmpProfile for addition of IGMP Profile
+// AddIgmpProfile for addition of IGMP Profile
 func (va *VoltApplication) AddIgmpProfile(cntx context.Context, igmpProfileConfig *common.IGMPConfig) error {
 	var igmpProfile *IgmpProfile
 
@@ -1724,7 +1703,7 @@
 	return nil
 }
 
-//UpdateIgmpProfile for addition of IGMP Profile
+// UpdateIgmpProfile for addition of IGMP Profile
 func (va *VoltApplication) UpdateIgmpProfile(cntx context.Context, igmpProfileConfig *common.IGMPConfig) error {
 	igmpProfile := va.checkIgmpProfileMap(igmpProfileConfig.ProfileID)
 	if igmpProfile == nil {
@@ -1738,7 +1717,7 @@
 
 	keepAliveInterval := uint32(igmpProfileConfig.KeepAliveInterval)
 
-	//KeepAliveInterval should have a min of 10 seconds
+	// KeepAliveInterval should have a min of 10 seconds
 	if keepAliveInterval < MinKeepAliveInterval {
 		keepAliveInterval = MinKeepAliveInterval
 		logger.Infow(ctx, "Auto adjust keepAliveInterval - Value < 10", log.Fields{"Received": igmpProfileConfig.KeepAliveInterval, "Configured": keepAliveInterval})
@@ -1845,7 +1824,6 @@
 
 // sendGeneralQuery to send general query
 func sendGeneralQuery(device string, port string, cVlan of.VlanType, pbit uint8, proxyCfg *IgmpProfile, proxyIP *net.IP) {
-
 	if queryPkt, err := Igmpv2QueryPacket(AllSystemsMulticastGroupIP, cVlan, *proxyIP, pbit, proxyCfg.MaxResp); err == nil {
 		if err := cntlr.GetController().PacketOutReq(device, port, port, queryPkt, false); err != nil {
 			logger.Warnw(ctx, "General Igmpv2 Query Failed to send", log.Fields{"Device": device, "Port": port, "Packet": queryPkt, "Pbit": pbit})
diff --git a/internal/pkg/application/igmpgroup.go b/internal/pkg/application/igmpgroup.go
index a7107cd..2dab424 100644
--- a/internal/pkg/application/igmpgroup.go
+++ b/internal/pkg/application/igmpgroup.go
@@ -11,7 +11,7 @@
 * 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 application
 
@@ -34,19 +34,19 @@
 // connected via multiple devices (OLTs). The IGMP group is stored on the
 // VOLT application.
 type IgmpGroup struct {
-	GroupID               uint32
-	Mvlan                 of.VlanType
-	PonVlan               of.VlanType
-	GroupName             string
-	GroupAddr             net.IP
 	Devices               map[string]*IgmpGroupDevice `json:"-"`
 	PendingGroupForDevice map[string]time.Time        //map [deviceId, timestamp]  (ExpiryTime  = leave time + 15mins)
 	Version               string
+	GroupName             string
+	GroupAddr             net.IP
+	PendingPoolLock       sync.RWMutex
+	IgmpGroupLock         sync.RWMutex
+	GroupID               uint32
+	Mvlan                 of.VlanType
+	PonVlan               of.VlanType
 	IsPonVlanPresent      bool
 	IsChannelBasedGroup   bool
-	PendingPoolLock       sync.RWMutex
 	IsGroupStatic         bool
-	IgmpGroupLock         sync.RWMutex
 }
 
 // NewIgmpGroup is constructor for an IGMP group
@@ -78,7 +78,6 @@
 
 // IgmpGroupReInit to re-initialize igmp group members
 func (ig *IgmpGroup) IgmpGroupReInit(cntx context.Context, name string, gip net.IP) {
-
 	logger.Infow(ctx, "Reinitialize Igmp Group", log.Fields{"GroupID": ig.GroupID, "OldName": ig.GroupName, "Name": name, "OldAddr": ig.GroupAddr.String(), "GroupAddr": gip.String()})
 
 	ig.GroupName = name
@@ -112,9 +111,8 @@
 	}
 }
 
-//HandleGroupMigration - handles migration of group members between static & dynamic
+// HandleGroupMigration - handles migration of group members between static & dynamic
 func (ig *IgmpGroup) HandleGroupMigration(cntx context.Context, deviceID string, groupAddr net.IP) {
-
 	var group *layers.IGMPv3GroupRecord
 	app := GetApplication()
 	if deviceID == "" {
@@ -191,11 +189,10 @@
 	}
 	igd.DelAllChannels(cntx)
 
-	//Clear all internal maps so that the groups can be reused
+	// Clear all internal maps so that the groups can be reused
 	igd.PortChannelMap.Range(func(key, value interface{}) bool {
-
-		//Update the counters only if not already updated
-		//(i.e) 1. In case of channel remove during Mvlan Update
+		// Update the counters only if not already updated
+		// (i.e) 1. In case of channel remove during Mvlan Update
 		if countersToBeUpdated {
 			port := key.(string)
 			channelList := value.([]net.IP)
@@ -225,7 +222,6 @@
 // there is not response for IGMP query from the receiver
 func (ig *IgmpGroup) AddReceiver(cntx context.Context, device string, port string, groupIP net.IP,
 	group *layers.IGMPv3GroupRecord, ver uint8, cvlan uint16, pbit uint8, ponPort uint32) {
-
 	logger.Debugw(ctx, "Adding Receiver", log.Fields{"Port": port})
 	if igd, ok := ig.getIgmpGroupDevice(cntx, device); !ok {
 		igd = ig.AddIgmpGroupDevice(cntx, device, ig.GroupID, ver)
@@ -272,7 +268,6 @@
 	logger.Infow(ctx, "Port Channel List", log.Fields{"Port": port, "IPsList": ipsList})
 	igd.PortChannelMap.Range(printPortChannel)
 
-
 	for _, groupAddr := range ipsList {
 		logger.Debugw(ctx, "Port Channels", log.Fields{"Port": port, "IPsList": ipsList, "GroupAddr": groupAddr, "Len": len(ipsList)})
 		igd.DelReceiver(cntx, groupAddr, port, nil, ponPortID)
@@ -298,7 +293,6 @@
 
 // GetAllIgmpChannelForDevice - Returns all channels with active members associated to the Igmp Group for the given device
 func (ig *IgmpGroup) GetAllIgmpChannelForDevice(deviceID string) map[string]string {
-
 	if deviceID == "" {
 		return ig.GetAllIgmpChannel()
 	}
@@ -417,7 +411,7 @@
 		if igdChangeCnt > 0 {
 			if err := igd.WriteToDb(cntx); err != nil {
 				logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device,
-							"GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
+					"GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
 			}
 		}
 	}
@@ -434,7 +428,6 @@
 			if igd.NumReceivers() == 0 {
 				ig.DelIgmpGroupDevice(cntx, igd)
 			}
-
 		} else {
 			logger.Info(ctx, "Skipping Expiry since Device is unavailable")
 		}
@@ -456,7 +449,7 @@
 	defer mvp.mvpLock.RUnlock()
 	group := mvp.Groups[ig.GroupName]
 
-	//Case where mvlan update in-progress
+	// Case where mvlan update in-progress
 	if group == nil || len(group.McIPs) == 0 {
 		return 0
 	}
@@ -498,7 +491,6 @@
 
 // RestoreDevices : IGMP group write to DB
 func (ig *IgmpGroup) RestoreDevices(cntx context.Context) {
-
 	ig.migrateIgmpDevices(cntx)
 	devices, _ := db.GetIgmpDevices(cntx, ig.Mvlan, ig.GroupName, ig.GroupAddr)
 	for _, device := range devices {
@@ -529,7 +521,7 @@
 				igd.QueryExpiryTime = time.Now().Add(time.Duration(igd.proxyCfg.KeepAliveInterval) * time.Second)
 				if err := igd.WriteToDb(cntx); err != nil {
 					logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device,
-								"GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
+						"GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
 				}
 			}
 
@@ -560,92 +552,89 @@
 
 // WriteToDb is utility to write Igmp Group Info to database
 func (ig *IgmpGroup) WriteToDb(cntx context.Context) error {
-        ig.Version = database.PresentVersionMap[database.IgmpGroupPath]
-        b, err := json.Marshal(ig)
-        if err != nil {
-                return err
-        }
-        if err1 := db.PutIgmpGroup(cntx, ig.getKey(), string(b)); err1 != nil {
-                return err1
-        }
-        return nil
+	ig.Version = database.PresentVersionMap[database.IgmpGroupPath]
+	b, err := json.Marshal(ig)
+	if err != nil {
+		return err
+	}
+	if err1 := db.PutIgmpGroup(cntx, ig.getKey(), string(b)); err1 != nil {
+		return err1
+	}
+	return nil
 }
 
 // UpdateIgmpGroup : When the pending group is allocated to new
 func (ig *IgmpGroup) UpdateIgmpGroup(cntx context.Context, oldKey, newKey string) {
+	// If the group is allocated to same McastGroup, no need to update the
+	// IgmpGroups map
+	if oldKey == newKey {
+		return
+	}
+	logger.Infow(ctx, "Updating Igmp Group with new MVP Group Info", log.Fields{"OldKey": oldKey, "NewKey": newKey, "GroupID": ig.GroupID})
 
-        //If the group is allocated to same McastGroup, no need to update the
-        //IgmpGroups map
-        if oldKey == newKey {
-                return
-        }
-        logger.Infow(ctx, "Updating Igmp Group with new MVP Group Info", log.Fields{"OldKey": oldKey, "NewKey": newKey, "GroupID": ig.GroupID})
+	GetApplication().IgmpGroups.Delete(oldKey)
+	_ = db.DelIgmpGroup(cntx, oldKey)
 
-        GetApplication().IgmpGroups.Delete(oldKey)
-        _ = db.DelIgmpGroup(cntx, oldKey)
-
-        GetApplication().IgmpGroups.Store(newKey, ig)
-        if err := ig.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Igmp group Write to DB failed", log.Fields{"groupName": ig.GroupName})
-        }
+	GetApplication().IgmpGroups.Store(newKey, ig)
+	if err := ig.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Igmp group Write to DB failed", log.Fields{"groupName": ig.GroupName})
+	}
 }
 
 func (ig *IgmpGroup) removeExpiredGroupFromDevice(cntx context.Context) {
-        ig.PendingPoolLock.Lock()
-        defer ig.PendingPoolLock.Unlock()
+	ig.PendingPoolLock.Lock()
+	defer ig.PendingPoolLock.Unlock()
 
-        for device, timer := range ig.PendingGroupForDevice {
+	for device, timer := range ig.PendingGroupForDevice {
+		// To ensure no race-condition between the expiry time and the new Join,
+		// ensure the group exists in pending pool before deletion
+		groupExistsInPendingPool := true
 
-                // To ensure no race-condition between the expiry time and the new Join,
-                // ensure the group exists in pending pool before deletion
-                groupExistsInPendingPool := true
+		if !time.Now().After(timer) {
+			continue
+		}
 
-                if !time.Now().After(timer) {
-                        continue
-                }
+		// Check if the IgmpGroup obj has no active member across any device
+		// If Yes, then this group is part of global pending pool (IgmpPendingPool), hence if expired,
+		// Remove only the IgmpGroup obj referenced to this device from global pool also.
+		if ig.NumDevicesActive() == 0 {
+			groupExistsInPendingPool = GetApplication().RemoveGroupFromPendingPool(device, ig)
+		}
 
-                // Check if the IgmpGroup obj has no active member across any device
-                // If Yes, then this group is part of global pending pool (IgmpPendingPool), hence if expired,
-                // Remove only the IgmpGroup obj referenced to this device from global pool also.
-                if ig.NumDevicesActive() == 0 {
-                        groupExistsInPendingPool = GetApplication().RemoveGroupFromPendingPool(device, ig)
-                }
-
-                // Remove the group entry from device and remove the IgmpDev Obj
-                // from IgmpGrp Pending pool
-                if groupExistsInPendingPool {
-                        ig.DeleteIgmpGroupDevice(cntx, device)
-                }
-        }
+		// Remove the group entry from device and remove the IgmpDev Obj
+		// from IgmpGrp Pending pool
+		if groupExistsInPendingPool {
+			ig.DeleteIgmpGroupDevice(cntx, device)
+		}
+	}
 }
 
-//DeleteIgmpGroupDevice - removes the IgmpGroupDevice obj from IgmpGroup and database
+// DeleteIgmpGroupDevice - removes the IgmpGroupDevice obj from IgmpGroup and database
 func (ig *IgmpGroup) DeleteIgmpGroupDevice(cntx context.Context, device string) {
+	logger.Infow(ctx, "Deleting IgmpGroupDevice from IG Pending Pool", log.Fields{"Device": device, "GroupID": ig.GroupID, "GroupName": ig.GroupName, "GroupAddr": ig.GroupAddr.String(), "PendingDevices": len(ig.Devices)})
 
-        logger.Infow(ctx, "Deleting IgmpGroupDevice from IG Pending Pool", log.Fields{"Device": device, "GroupID": ig.GroupID, "GroupName": ig.GroupName, "GroupAddr": ig.GroupAddr.String(), "PendingDevices": len(ig.Devices)})
+	igd := ig.Devices[device]
+	igd.DelMcGroup(true)
+	delete(ig.Devices, device)
+	delete(ig.PendingGroupForDevice, device)
+	_ = db.DelIgmpDevice(cntx, igd.Mvlan, igd.GroupName, igd.GroupAddr, igd.Device)
 
-        igd := ig.Devices[device]
-        igd.DelMcGroup(true)
-        delete(ig.Devices, device)
-        delete(ig.PendingGroupForDevice, device)
-        _ = db.DelIgmpDevice(cntx, igd.Mvlan, igd.GroupName, igd.GroupAddr, igd.Device)
-
-        //If the group is not associated to any other device, then the entire Igmp Group obj itself can be removed
-        if ig.NumDevicesAll() == 0 {
-                logger.Infow(ctx, "Deleting IgmpGroup as all pending groups has expired", log.Fields{"Device": device, "GroupID": ig.GroupID, "GroupName": ig.GroupName, "GroupAddr": ig.GroupAddr.String(), "PendingDevices": len(ig.Devices)})
-                GetApplication().DelIgmpGroup(cntx, ig)
-                return
-        }
-        if err := ig.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Igmp group Write to DB failed", log.Fields{"groupName": ig.GroupName})
-        }
+	// If the group is not associated to any other device, then the entire Igmp Group obj itself can be removed
+	if ig.NumDevicesAll() == 0 {
+		logger.Infow(ctx, "Deleting IgmpGroup as all pending groups has expired", log.Fields{"Device": device, "GroupID": ig.GroupID, "GroupName": ig.GroupName, "GroupAddr": ig.GroupAddr.String(), "PendingDevices": len(ig.Devices)})
+		GetApplication().DelIgmpGroup(cntx, ig)
+		return
+	}
+	if err := ig.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Igmp group Write to DB failed", log.Fields{"groupName": ig.GroupName})
+	}
 }
 
 // DelIgmpGroup deletes all devices for the provided igmp group
 func (ig *IgmpGroup) DelIgmpGroup(cntx context.Context) {
-        logger.Infow(ctx, "Deleting All Device for Group", log.Fields{"Group": ig.GroupName})
-        for _, igd := range ig.Devices {
-                ig.DelIgmpGroupDevice(cntx, igd)
-        }
-        GetApplication().DelIgmpGroup(cntx, ig)
+	logger.Infow(ctx, "Deleting All Device for Group", log.Fields{"Group": ig.GroupName})
+	for _, igd := range ig.Devices {
+		ig.DelIgmpGroupDevice(cntx, igd)
+	}
+	GetApplication().DelIgmpGroup(cntx, ig)
 }
diff --git a/internal/pkg/application/igmpgroupchannel.go b/internal/pkg/application/igmpgroupchannel.go
index d17e209..d8a2644 100644
--- a/internal/pkg/application/igmpgroupchannel.go
+++ b/internal/pkg/application/igmpgroupchannel.go
@@ -11,7 +11,7 @@
 * 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 application
 
@@ -23,714 +23,704 @@
 	"github.com/google/gopacket/layers"
 
 	cntlr "voltha-go-controller/internal/pkg/controller"
-	"voltha-go-controller/internal/pkg/types"
 	"voltha-go-controller/internal/pkg/of"
+	common "voltha-go-controller/internal/pkg/types"
 	"voltha-go-controller/log"
 )
 
 // IgmpGroupChannel structure
 type IgmpGroupChannel struct {
-        Device       string
-        GroupID      uint32
-        GroupName    string
-        GroupAddr    net.IP
-        Mvlan        of.VlanType
-        Exclude      int
-        ExcludeList  []net.IP
-        IncludeList  []net.IP
-        Version      uint8
-        ServVersion  *uint8                    `json:"-"`
-        CurReceivers map[string]*IgmpGroupPort `json:"-"`
-        NewReceivers map[string]*IgmpGroupPort `json:"-"`
-        proxyCfg     **IgmpProfile
-        IgmpProxyIP  **net.IP                  `json:"-"`
+	CurReceivers map[string]*IgmpGroupPort `json:"-"`
+	NewReceivers map[string]*IgmpGroupPort `json:"-"`
+	proxyCfg     **IgmpProfile
+	IgmpProxyIP  **net.IP `json:"-"`
+	ServVersion  *uint8
+	Device       string
+	GroupName    string
+	GroupAddr    net.IP
+	ExcludeList  []net.IP
+	IncludeList  []net.IP `json:"-"`
+	Exclude      int
+	GroupID      uint32
+	Mvlan        of.VlanType
+	Version      uint8
 }
 
 // NewIgmpGroupChannel is constructor for a channel. The default IGMP version is set to 3
 // as the protocol defines the way to manage backward compatibility
-// The implementation handles simultaneous presense of lower versioned
+// The implementation handles simultaneous presence of lower versioned
 // receivers
 func NewIgmpGroupChannel(igd *IgmpGroupDevice, groupAddr net.IP, version uint8) *IgmpGroupChannel {
-        var igc IgmpGroupChannel
-        igc.Device = igd.Device
-        igc.GroupID = igd.GroupID
-        igc.GroupName = igd.GroupName
-        igc.GroupAddr = groupAddr
-        igc.Mvlan = igd.Mvlan
-        igc.Version = version
-        igc.CurReceivers = make(map[string]*IgmpGroupPort)
-        igc.NewReceivers = make(map[string]*IgmpGroupPort)
-        igc.proxyCfg = &igd.proxyCfg
-        igc.IgmpProxyIP = &igd.IgmpProxyIP
-        igc.ServVersion = igd.ServVersion
-        return &igc
+	var igc IgmpGroupChannel
+	igc.Device = igd.Device
+	igc.GroupID = igd.GroupID
+	igc.GroupName = igd.GroupName
+	igc.GroupAddr = groupAddr
+	igc.Mvlan = igd.Mvlan
+	igc.Version = version
+	igc.CurReceivers = make(map[string]*IgmpGroupPort)
+	igc.NewReceivers = make(map[string]*IgmpGroupPort)
+	igc.proxyCfg = &igd.proxyCfg
+	igc.IgmpProxyIP = &igd.IgmpProxyIP
+	igc.ServVersion = igd.ServVersion
+	return &igc
 }
 
 // NewIgmpGroupChannelFromBytes create the IGMP group channel from a byte slice
 func NewIgmpGroupChannelFromBytes(b []byte) (*IgmpGroupChannel, error) {
-        var igc IgmpGroupChannel
-        if err := json.Unmarshal(b, &igc); err != nil {
-                return nil, err
-        }
-        igc.CurReceivers = make(map[string]*IgmpGroupPort)
-        igc.NewReceivers = make(map[string]*IgmpGroupPort)
-        return &igc, nil
+	var igc IgmpGroupChannel
+	if err := json.Unmarshal(b, &igc); err != nil {
+		return nil, err
+	}
+	igc.CurReceivers = make(map[string]*IgmpGroupPort)
+	igc.NewReceivers = make(map[string]*IgmpGroupPort)
+	return &igc, nil
 }
 
 // RestorePorts to restore ports
 func (igc *IgmpGroupChannel) RestorePorts(cntx context.Context) {
-
-        igc.migrateIgmpPorts(cntx)
-        ports, _ := db.GetIgmpRcvrs(cntx, igc.Mvlan, igc.GroupAddr, igc.Device)
-        for _, port := range ports {
-                b, ok := port.Value.([]byte)
-                if !ok {
-                        logger.Warn(ctx, "The value type is not []byte")
-                        continue
-                }
-                if igp, err := NewIgmpGroupPortFromBytes(b); err == nil {
-                        igc.NewReceivers[igp.Port] = igp
-                        logger.Infow(ctx, "Group Port Restored", log.Fields{"IGP": igp})
-                } else {
-                        logger.Warn(ctx, "Failed to decode port from DB")
-                }
-        }
-        if err := igc.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
-        }
+	igc.migrateIgmpPorts(cntx)
+	ports, _ := db.GetIgmpRcvrs(cntx, igc.Mvlan, igc.GroupAddr, igc.Device)
+	for _, port := range ports {
+		b, ok := port.Value.([]byte)
+		if !ok {
+			logger.Warn(ctx, "The value type is not []byte")
+			continue
+		}
+		if igp, err := NewIgmpGroupPortFromBytes(b); err == nil {
+			igc.NewReceivers[igp.Port] = igp
+			logger.Infow(ctx, "Group Port Restored", log.Fields{"IGP": igp})
+		} else {
+			logger.Warn(ctx, "Failed to decode port from DB")
+		}
+	}
+	if err := igc.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
+	}
 }
 
 // WriteToDb is utility to write IGMPGroupChannel Info to database
 func (igc *IgmpGroupChannel) WriteToDb(cntx context.Context) error {
-        b, err := json.Marshal(igc)
-        if err != nil {
-                return err
-        }
-        if err1 := db.PutIgmpChannel(cntx, igc.Mvlan, igc.GroupName, igc.Device, igc.GroupAddr, string(b)); err1 != nil {
-                return err1
-        }
-        logger.Info(ctx, "IGC Updated")
-        return nil
+	b, err := json.Marshal(igc)
+	if err != nil {
+		return err
+	}
+	if err1 := db.PutIgmpChannel(cntx, igc.Mvlan, igc.GroupName, igc.Device, igc.GroupAddr, string(b)); err1 != nil {
+		return err1
+	}
+	logger.Info(ctx, "IGC Updated")
+	return nil
 }
 
-
 // InclSourceIsIn checks if a source is in include list
 func (igc *IgmpGroupChannel) InclSourceIsIn(src net.IP) bool {
-        return IsIPPresent(src, igc.IncludeList)
+	return IsIPPresent(src, igc.IncludeList)
 }
 
 // ExclSourceIsIn checks if a source is in exclude list
 func (igc *IgmpGroupChannel) ExclSourceIsIn(src net.IP) bool {
-        return IsIPPresent(src, igc.ExcludeList)
+	return IsIPPresent(src, igc.ExcludeList)
 }
 
 // AddInclSource adds a source is in include list
 func (igc *IgmpGroupChannel) AddInclSource(src net.IP) {
-        logger.Debugw(ctx, "Adding Include Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Src": src})
-        igc.IncludeList = append(igc.IncludeList, src)
+	logger.Debugw(ctx, "Adding Include Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Src": src})
+	igc.IncludeList = append(igc.IncludeList, src)
 }
 
 // AddExclSource adds a source is in exclude list
 func (igc *IgmpGroupChannel) AddExclSource(src net.IP) {
-        logger.Debugw(ctx, "Adding Exclude Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Src": src})
-        igc.ExcludeList = append(igc.ExcludeList, src)
+	logger.Debugw(ctx, "Adding Exclude Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Src": src})
+	igc.ExcludeList = append(igc.ExcludeList, src)
 }
 
 // UpdateExclSource update excl source list for the given channel
 func (igc *IgmpGroupChannel) UpdateExclSource(srcList []net.IP) bool {
+	logger.Debugw(ctx, "Updating Exclude Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Current List": igc.ExcludeList, "Incoming List": srcList})
+	if !igc.IsExclListChanged(srcList) {
+		return false
+	}
 
-        logger.Debugw(ctx, "Updating Exclude Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Current List": igc.ExcludeList, "Incoming List": srcList})
-        if !igc.IsExclListChanged(srcList) {
-                return false
-        }
+	if igc.NumReceivers() == 1 {
+		igc.ExcludeList = srcList
+	} else {
+		igc.ExcludeList = igc.computeExclList(srcList)
+	}
 
-        if igc.NumReceivers() == 1 {
-                igc.ExcludeList = srcList
-        } else {
-                igc.ExcludeList = igc.computeExclList(srcList)
-        }
-
-        logger.Debugw(ctx, "Updated Exclude Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Updated Excl List": igc.ExcludeList})
-        return true
+	logger.Debugw(ctx, "Updated Exclude Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Updated Excl List": igc.ExcludeList})
+	return true
 }
 
-// computeExclList computes intersection of pervious & current src list
+// computeExclList computes intersection of previous & current src list
 func (igc *IgmpGroupChannel) computeExclList(srcList []net.IP) []net.IP {
-
-        updatedSrcList := []net.IP{}
-        for _, src := range srcList {
-                for _, excl := range igc.ExcludeList {
-                        if src.Equal(excl) {
-                                updatedSrcList = append(updatedSrcList, src)
-                        }
-                }
-        }
-        return updatedSrcList
+	updatedSrcList := []net.IP{}
+	for _, src := range srcList {
+		for _, excl := range igc.ExcludeList {
+			if src.Equal(excl) {
+				updatedSrcList = append(updatedSrcList, src)
+			}
+		}
+	}
+	return updatedSrcList
 }
 
 // IsExclListChanged checks if excl list has been updated
 func (igc *IgmpGroupChannel) IsExclListChanged(srcList []net.IP) bool {
+	srcPresent := false
+	if len(igc.ExcludeList) != len(srcList) {
+		return true
+	}
 
-        srcPresent := false
-        if len(igc.ExcludeList) != len(srcList) {
-                return true
-        }
-
-        for _, src := range srcList {
-                for _, excl := range igc.ExcludeList {
-                        srcPresent = false
-                        if src.Equal(excl) {
-                                srcPresent = true
-                                break
-                        }
-                }
-                if !srcPresent {
-                        return true
-                }
-        }
-        return false
+	for _, src := range srcList {
+		for _, excl := range igc.ExcludeList {
+			srcPresent = false
+			if src.Equal(excl) {
+				srcPresent = true
+				break
+			}
+		}
+		if !srcPresent {
+			return true
+		}
+	}
+	return false
 }
 
 // DelInclSource deletes a source is in include list
 func (igc *IgmpGroupChannel) DelInclSource(src net.IP) {
-        mvp := GetApplication().GetMvlanProfileByTag(igc.Mvlan)
-        /* If the SSM proxy is configured, then we can del the src ip from igc as whatever is in proxy that is final list */
-        if _, ok := mvp.Proxy[igc.GroupName]; !ok {
-                logger.Debugw(ctx, "Deleting Include Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Src": src})
-                for _, igp := range igc.CurReceivers {
-                        if igp.InclSourceIsIn(src) {
-                                logger.Infow(ctx, "Skipping deletion: Source Present for another Receiver", log.Fields{"Receiver": igp.Port})
-                                return
-                        }
-                }
-                for _, igp := range igc.NewReceivers {
-                        if igp.InclSourceIsIn(src) {
-                                logger.Infow(ctx, "Skipping deletion: Source Present for another Receiver", log.Fields{"Receiver": igp.Port})
-                                return
-                        }
-                }
-        } else {
-                logger.Debug(ctx, "Proxy configured, not Deleting Include Source for Channel")
-        }
-        for i, addr := range igc.IncludeList {
-                if addr.Equal(src) {
-                        igc.IncludeList = append(igc.IncludeList[:i], igc.IncludeList[i+1:]...)
-                        return
-                }
-        }
+	mvp := GetApplication().GetMvlanProfileByTag(igc.Mvlan)
+	/* If the SSM proxy is configured, then we can del the src ip from igc as whatever is in proxy that is final list */
+	if _, ok := mvp.Proxy[igc.GroupName]; !ok {
+		logger.Debugw(ctx, "Deleting Include Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Src": src})
+		for _, igp := range igc.CurReceivers {
+			if igp.InclSourceIsIn(src) {
+				logger.Infow(ctx, "Skipping deletion: Source Present for another Receiver", log.Fields{"Receiver": igp.Port})
+				return
+			}
+		}
+		for _, igp := range igc.NewReceivers {
+			if igp.InclSourceIsIn(src) {
+				logger.Infow(ctx, "Skipping deletion: Source Present for another Receiver", log.Fields{"Receiver": igp.Port})
+				return
+			}
+		}
+	} else {
+		logger.Debug(ctx, "Proxy configured, not Deleting Include Source for Channel")
+	}
+	for i, addr := range igc.IncludeList {
+		if addr.Equal(src) {
+			igc.IncludeList = append(igc.IncludeList[:i], igc.IncludeList[i+1:]...)
+			return
+		}
+	}
 }
 
 // DelExclSource deletes a source is in exclude list
 func (igc *IgmpGroupChannel) DelExclSource(src net.IP) {
-        logger.Debugw(ctx, "Deleting Exclude Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Src": src})
+	logger.Debugw(ctx, "Deleting Exclude Source for Channel", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device, "Src": src})
 
-        for _, igp := range igc.CurReceivers {
-                if igp.ExclSourceIsIn(src) {
-                        logger.Infow(ctx, "Skipping deletion: Source Present for another Receiver", log.Fields{"Receiver": igp.Port})
-                        return
-                }
-        }
-        for _, igp := range igc.NewReceivers {
-                if igp.ExclSourceIsIn(src) {
-                        logger.Infow(ctx, "Skipping deletion: Source Present for another Receiver", log.Fields{"Receiver": igp.Port})
-                        return
-                }
-        }
-        for i, addr := range igc.ExcludeList {
-                if addr.Equal(src) {
-                        igc.ExcludeList = append(igc.ExcludeList[:i], igc.ExcludeList[i+1:]...)
-                        return
-                }
-        }
+	for _, igp := range igc.CurReceivers {
+		if igp.ExclSourceIsIn(src) {
+			logger.Infow(ctx, "Skipping deletion: Source Present for another Receiver", log.Fields{"Receiver": igp.Port})
+			return
+		}
+	}
+	for _, igp := range igc.NewReceivers {
+		if igp.ExclSourceIsIn(src) {
+			logger.Infow(ctx, "Skipping deletion: Source Present for another Receiver", log.Fields{"Receiver": igp.Port})
+			return
+		}
+	}
+	for i, addr := range igc.ExcludeList {
+		if addr.Equal(src) {
+			igc.ExcludeList = append(igc.ExcludeList[:i], igc.ExcludeList[i+1:]...)
+			return
+		}
+	}
 }
 
 // ProcessSources process the received list of either included sources or the excluded sources
 // The return value indicate sif the group is modified and needs to be informed
 // to the upstream multicast servers
 func (igc *IgmpGroupChannel) ProcessSources(cntx context.Context, port string, ip []net.IP, incl bool) (bool, bool) {
-        groupChanged := false
-        groupExclUpdated := false
-        receiverSrcListEmpty := false
-        // If the version type is 2, there isn't anything to process here
-        if igc.Version == IgmpVersion2 && *igc.ServVersion == IgmpVersion2 {
-                return false, false
-        }
+	groupChanged := false
+	groupExclUpdated := false
+	receiverSrcListEmpty := false
+	// If the version type is 2, there isn't anything to process here
+	if igc.Version == IgmpVersion2 && *igc.ServVersion == IgmpVersion2 {
+		return false, false
+	}
 
-        igp := igc.GetReceiver(port)
-        if igp == nil {
-                logger.Warnw(ctx, "Receiver not found", log.Fields{"Port": port})
-                return false, false
-        }
-        mvp := GetApplication().GetMvlanProfileByTag(igc.Mvlan)
-        if incl {
-                for _, src := range ip {
+	igp := igc.GetReceiver(port)
+	if igp == nil {
+		logger.Warnw(ctx, "Receiver not found", log.Fields{"Port": port})
+		return false, false
+	}
+	mvp := GetApplication().GetMvlanProfileByTag(igc.Mvlan)
+	if incl {
+		for _, src := range ip {
+			if igp.ExclSourceIsIn(src) {
+				igp.DelExclSource(src)
+				if igc.ExclSourceIsIn(src) {
+					igc.DelExclSource(src)
+					groupChanged = true
+				}
+			}
 
-                        if igp.ExclSourceIsIn(src) {
-                                igp.DelExclSource(src)
-                                if igc.ExclSourceIsIn(src) {
-                                        igc.DelExclSource(src)
-                                        groupChanged = true
-                                }
-                        }
+			// If the source is not in the list of include sources for the port
+			// add it. If so, check also if it is in list of include sources
+			// at the device level.
+			if !igp.InclSourceIsIn(src) {
+				igp.AddInclSource(src)
+				if !igc.InclSourceIsIn(src) {
+					igc.AddInclSource(src)
+					groupChanged = true
+				}
+			}
+		}
+		/* If any of the existing ip in the source list is removed we need to remove from the list in igp and igc */
+		if _, ok := mvp.Proxy[igc.GroupName]; ok {
+			/* If we get leave message from any subscriber, we do not have to delete the entries in the src list
+			   Only if there is any modification in the src list by proxy config update only then we need to update */
+			if len(ip) != 0 && len(ip) != len(igc.IncludeList) {
+				for i := len(igc.IncludeList) - 1; i >= 0; i-- {
+					src := igc.IncludeList[i]
+					if !IsIPPresent(src, ip) {
+						igp.DelInclSource(src)
+						igc.DelInclSource(src)
+						groupChanged = true
+					}
+				}
+			}
+		}
+	} else {
+		for _, src := range ip {
+			if igp.InclSourceIsIn(src) {
+				igp.DelInclSource(src)
+				if igc.InclSourceIsIn(src) {
+					igc.DelInclSource(src)
+					groupChanged = true
+				}
+				if len(igp.IncludeList) == 0 {
+					receiverSrcListEmpty = true
+				}
+			}
 
-                        // If the source is not in the list of include sources for the port
-                        // add it. If so, check also if it is in list of include sources
-                        // at the device level.
-                        if !igp.InclSourceIsIn(src) {
-                                igp.AddInclSource(src)
-                                if !igc.InclSourceIsIn(src) {
-                                        igc.AddInclSource(src)
-                                        groupChanged = true
-                                }
-                        }
-                }
-                /* If any of the existing ip in the source list is removed we need to remove from the list in igp and igc */
-                if _, ok := mvp.Proxy[igc.GroupName]; ok {
-                        /* If we get leave message from any subscriber, we do not have to delete the entries in the src list
-                           Only if ther is any modification in the src list by proxy config update only then we need to update */
-                        if len(ip) != 0 && len(ip) != len(igc.IncludeList) {
-                                for i := len(igc.IncludeList) - 1; i >= 0; i-- {
-                                        src := igc.IncludeList[i]
-                                        if !IsIPPresent(src, ip) {
-                                                igp.DelInclSource(src)
-                                                igc.DelInclSource(src)
-                                                groupChanged = true
-                                        }
-                                }
-                        }
-                }
-        } else {
-                for _, src := range ip {
-
-                        if igp.InclSourceIsIn(src) {
-                                igp.DelInclSource(src)
-                                if igc.InclSourceIsIn(src) {
-                                        igc.DelInclSource(src)
-                                        groupChanged = true
-                                }
-                                if len(igp.IncludeList) == 0 {
-                                        receiverSrcListEmpty = true
-                                }
-                        }
-
-                        // If the source is not in the list of exclude sources for the port
-                        // add it. If so, check also if it is in list of include sources
-                        // at the device level.
-                        if !igp.ExclSourceIsIn(src) {
-                                igp.AddExclSource(src)
-                                /* If there is any update in the src list of proxy we need to update the igc */
-                                if _, ok := mvp.Proxy[igc.GroupName]; ok {
-                                        if !igc.ExclSourceIsIn(src) {
-                                                igc.AddExclSource(src)
-                                                groupChanged = true
-                                        }
-                                }
-                        }
-                }
-                /* If any of the existing ip in the source list is removed we need to remove from the list in igp and igc */
-                if _, ok := mvp.Proxy[igc.GroupName]; ok {
-                        if len(ip) != len(igc.ExcludeList) {
-                                for i := len(igc.ExcludeList) - 1; i >= 0; i-- {
-                                        src := igc.ExcludeList[i]
-                                        if !IsIPPresent(src, ip) {
-                                                igp.DelExclSource(src)
-                                                igc.DelExclSource(src)
-                                                groupChanged = true
-                                        }
-                                }
-                        }
-                }
-                groupExclUpdated = igc.UpdateExclSource(ip)
-        }
-        if err := igp.WriteToDb(cntx, igc.Mvlan, igc.GroupAddr, igc.Device); err != nil {
-                logger.Errorw(ctx, "Igmp group port Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
-        }
-        return (groupChanged || groupExclUpdated), receiverSrcListEmpty
+			// If the source is not in the list of exclude sources for the port
+			// add it. If so, check also if it is in list of include sources
+			// at the device level.
+			if !igp.ExclSourceIsIn(src) {
+				igp.AddExclSource(src)
+				/* If there is any update in the src list of proxy we need to update the igc */
+				if _, ok := mvp.Proxy[igc.GroupName]; ok {
+					if !igc.ExclSourceIsIn(src) {
+						igc.AddExclSource(src)
+						groupChanged = true
+					}
+				}
+			}
+		}
+		/* If any of the existing ip in the source list is removed we need to remove from the list in igp and igc */
+		if _, ok := mvp.Proxy[igc.GroupName]; ok {
+			if len(ip) != len(igc.ExcludeList) {
+				for i := len(igc.ExcludeList) - 1; i >= 0; i-- {
+					src := igc.ExcludeList[i]
+					if !IsIPPresent(src, ip) {
+						igp.DelExclSource(src)
+						igc.DelExclSource(src)
+						groupChanged = true
+					}
+				}
+			}
+		}
+		groupExclUpdated = igc.UpdateExclSource(ip)
+	}
+	if err := igp.WriteToDb(cntx, igc.Mvlan, igc.GroupAddr, igc.Device); err != nil {
+		logger.Errorw(ctx, "Igmp group port Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
+	}
+	return (groupChanged || groupExclUpdated), receiverSrcListEmpty
 }
 
 // GetReceiver to get receiver info
 func (igc *IgmpGroupChannel) GetReceiver(port string) *IgmpGroupPort {
-        igp := igc.NewReceivers[port]
-        if igp == nil {
-                igp = igc.CurReceivers[port]
-        }
-        return igp
+	igp := igc.NewReceivers[port]
+	if igp == nil {
+		igp = igc.CurReceivers[port]
+	}
+	return igp
 }
 
 // AddReceiver add the receiver to the device and perform other actions such as adding the group
 // to the physical device, add members, add flows to point the MC packets to the
 // group. Also, send a IGMP report upstream if there is a change in the group
 func (igc *IgmpGroupChannel) AddReceiver(cntx context.Context, port string, group *layers.IGMPv3GroupRecord, cvlan uint16, pbit uint8) bool {
+	var igp *IgmpGroupPort
+	var groupModified = false
+	var isNewReceiver = false
 
-        var igp *IgmpGroupPort
-        var groupModified = false
-        var isNewReceiver = false
+	var ip []net.IP
+	incl := false
+	mvp := GetApplication().GetMvlanProfileByTag(igc.Mvlan)
+	if _, ok := mvp.Proxy[igc.GroupName]; ok {
+		if mvp.Proxy[igc.GroupName].Mode == common.Include {
+			incl = true
+		}
+		ip = mvp.Proxy[igc.GroupName].SourceList
+	} else if group != nil {
+		incl = isIncl(group.Type)
+		ip = group.SourceAddresses
+	}
+	logger.Debugw(ctx, "Attempting to add receiver", log.Fields{"Version": igc.Version, "Port": port, "Incl": incl, "srcIp": ip})
 
-        var ip []net.IP
-        incl := false
-        mvp := GetApplication().GetMvlanProfileByTag(igc.Mvlan)
-        if _, ok := mvp.Proxy[igc.GroupName]; ok {
-                if mvp.Proxy[igc.GroupName].Mode == common.Include {
-                        incl = true
-                }
-                ip = mvp.Proxy[igc.GroupName].SourceList
-        } else if group != nil {
-                incl = isIncl(group.Type)
-                ip = group.SourceAddresses
-        }
-        logger.Debugw(ctx, "Attempting to add receiver", log.Fields{"Version": igc.Version, "Port": port, "Incl": incl, "srcIp": ip})
+	//logger.Infow(ctx, "Receivers", log.Fields{"New": igc.NewReceivers, "Current": igc.CurReceivers})
+	logger.Debugw(ctx, "Receiver Group", log.Fields{"Igd GId": igc.GroupID})
+	logger.Debugw(ctx, "Receiver Channel", log.Fields{"Igd addr": igc.GroupAddr})
+	logger.Debugw(ctx, "Receiver Mvlan", log.Fields{"Igd mvlan": igc.Mvlan})
+	logger.Debugw(ctx, "Receiver Sources", log.Fields{"Igd addr": ip})
 
-        //logger.Infow(ctx, "Receivers", log.Fields{"New": igc.NewReceivers, "Current": igc.CurReceivers})
-        logger.Debugw(ctx, "Receiver Group", log.Fields{"Igd GId": igc.GroupID})
-        logger.Debugw(ctx, "Receiver Channel", log.Fields{"Igd addr": igc.GroupAddr})
-        logger.Debugw(ctx, "Receiver Mvlan", log.Fields{"Igd mvlan": igc.Mvlan})
-        logger.Debugw(ctx, "Receiver Sources", log.Fields{"Igd addr": ip})
+	ponPortID := GetApplication().GetPonPortID(igc.Device, port)
 
-        ponPortID := GetApplication().GetPonPortID(igc.Device, port)
+	// Process the IGMP receiver. If it is already in, we should only process the changes
+	// to source list.
+	var newRcvExists bool
+	igp, newRcvExists = igc.NewReceivers[port]
+	if !newRcvExists {
+		// Add the receiver to the list of receivers and make the necessary group modification
+		// if this is the first time the receiver is added
+		var curRcvExists bool
+		if igp, curRcvExists = igc.CurReceivers[port]; curRcvExists {
+			logger.Debugw(ctx, "Existing IGMP receiver", log.Fields{"Group": igc.GroupAddr.String(), "Port": port})
+			delete(igc.CurReceivers, port)
+			igp.QueryTimeoutCount = 0
+			igc.NewReceivers[port] = igp
+		} else {
+			// New receiver who wasn't part of earlier list
+			// Need to send out IGMP group modification for this port
+			igp = NewIgmpGroupPort(port, cvlan, pbit, igc.Version, incl, uint32(ponPortID))
+			igc.NewReceivers[port] = igp
+			isNewReceiver = true
+			logger.Debugw(ctx, "New IGMP receiver", log.Fields{"Group": igc.GroupAddr.String(), "Port": port})
+			if len(igc.NewReceivers) == 1 && len(igc.CurReceivers) == 0 {
+				groupModified = true
+				igc.AddMcFlow(cntx)
+				logger.Debugw(ctx, "Added New Flow", log.Fields{"Group": igc.GroupAddr.String(), "Port": port})
+			}
+			if !incl {
+				igc.Exclude++
+			}
+		}
+	}
 
-        // Process the IGMP receiver. If it is already in, we should only process the changes
-        // to source list.
-        var newRcvExists bool
-        igp, newRcvExists = igc.NewReceivers[port]
-        if !newRcvExists {
-                // Add the receiver to the list of receivers and make the necessary group modification
-                // if this is the first time the receiver is added
-                var curRcvExists bool
-                if igp, curRcvExists = igc.CurReceivers[port]; curRcvExists {
-                        logger.Debugw(ctx, "Existing IGMP receiver", log.Fields{"Group": igc.GroupAddr.String(), "Port": port})
-                        delete(igc.CurReceivers, port)
-                        igp.QueryTimeoutCount = 0
-                        igc.NewReceivers[port] = igp
-                } else {
-                        // New receiver who wasn't part of earlier list
-                        // Need to send out IGMP group modification for this port
-                        igp = NewIgmpGroupPort(port, cvlan, pbit, igc.Version, incl, uint32(ponPortID))
-                        igc.NewReceivers[port] = igp
-                        isNewReceiver = true
-                        logger.Debugw(ctx, "New IGMP receiver", log.Fields{"Group": igc.GroupAddr.String(), "Port": port})
-                        if len(igc.NewReceivers) == 1 && len(igc.CurReceivers) == 0 {
-                                groupModified = true
-                                igc.AddMcFlow(cntx)
-                                logger.Debugw(ctx, "Added New Flow", log.Fields{"Group": igc.GroupAddr.String(), "Port": port})
-                        }
-                        if !incl {
-                                igc.Exclude++
-                        }
-                }
-        }
+	// Process the include/exclude list which may end up modifying the group
+	if change, _ := igc.ProcessSources(cntx, port, ip, incl); change {
+		groupModified = true
+	}
+	igc.ProcessMode(port, incl)
 
-        // Process the include/exclude list which may end up modifying the group
-        if change, _ := igc.ProcessSources(cntx, port, ip, incl); change {
-                groupModified = true
-        }
-        igc.ProcessMode(port, incl)
+	// If the group is modified as this is the first receiver or due to include/exclude list modification
+	// send a report to the upstream multicast servers
+	if groupModified {
+		logger.Debug(ctx, "Group Modified and IGMP report sent to the upstream server")
+		igc.SendReport(false)
+	} else if newRcvExists {
+		return false
+	}
 
-        // If the group is modified as this is the first receiver or due to include/exclude list modification
-        // send a report to the upstream multicast servers
-        if groupModified {
-                logger.Debug(ctx, "Group Modified and IGMP report sent to the upstream server")
-                igc.SendReport(false)
-        } else if newRcvExists {
-                return false
-        }
+	logger.Debugw(ctx, "Channel Receiver Added", log.Fields{"Group Channel": igc.GroupAddr, "Group Port": igp})
 
-        logger.Debugw(ctx, "Channel Receiver Added", log.Fields{"Group Channel": igc.GroupAddr, "Group Port": igp})
-
-        if err := igc.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
-        }
-        if err := igp.WriteToDb(cntx, igc.Mvlan, igc.GroupAddr, igc.Device); err != nil {
-                logger.Errorw(ctx, "Igmp group port Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
-        }
-        return isNewReceiver
+	if err := igc.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
+	}
+	if err := igp.WriteToDb(cntx, igc.Mvlan, igc.GroupAddr, igc.Device); err != nil {
+		logger.Errorw(ctx, "Igmp group port Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
+	}
+	return isNewReceiver
 }
 
 // DelReceiver is called when Query expiry happened for a receiver. This removes the receiver from the
 // the group
 func (igc *IgmpGroupChannel) DelReceiver(cntx context.Context, port string, incl bool, srcList []net.IP) bool {
-        // The receiver may exist either in NewReceiver list or
-        // the CurReceivers list. Find and remove it from either
-        // of the lists.
-        logger.Debugw(ctx, "Deleting Receiver from Channel", log.Fields{"Port": port, "SrcList": srcList, "Incl": incl})
-        logger.Debugw(ctx, "New Receivers", log.Fields{"New": igc.NewReceivers})
-        logger.Debugw(ctx, "Current Receivers", log.Fields{"Current": igc.CurReceivers})
+	// The receiver may exist either in NewReceiver list or
+	// the CurReceivers list. Find and remove it from either
+	// of the lists.
+	logger.Debugw(ctx, "Deleting Receiver from Channel", log.Fields{"Port": port, "SrcList": srcList, "Incl": incl})
+	logger.Debugw(ctx, "New Receivers", log.Fields{"New": igc.NewReceivers})
+	logger.Debugw(ctx, "Current Receivers", log.Fields{"Current": igc.CurReceivers})
 
-        receiversUpdated := false
-        groupModified, receiverSrcListEmpty := igc.ProcessSources(cntx, port, srcList, incl)
+	receiversUpdated := false
+	groupModified, receiverSrcListEmpty := igc.ProcessSources(cntx, port, srcList, incl)
 
-        if len(srcList) == 0 || len(igc.IncludeList) == 0 || receiverSrcListEmpty {
-                if igp, ok := igc.NewReceivers[port]; ok {
-                        logger.Debug(ctx, "Deleting from NewReceivers")
-                        delete(igc.NewReceivers, port)
-                        receiversUpdated = true
-                        if igp.Exclude {
-                                igc.Exclude--
-                        }
-                } else {
-                        if igp, ok1 := igc.CurReceivers[port]; ok1 {
-                                logger.Debug(ctx, "Deleting from CurReceivers")
-                                delete(igc.CurReceivers, port)
-                                receiversUpdated = true
-                                if igp.Exclude {
-                                        igc.Exclude--
-                                }
-                        } else {
-                                logger.Debug(ctx, "Receiver doesnot exist. Dropping Igmp leave")
-                                return false
-                        }
-                }
-                _ = db.DelIgmpRcvr(cntx, igc.Mvlan, igc.GroupAddr, igc.Device, port)
-        }
+	if len(srcList) == 0 || len(igc.IncludeList) == 0 || receiverSrcListEmpty {
+		if igp, ok := igc.NewReceivers[port]; ok {
+			logger.Debug(ctx, "Deleting from NewReceivers")
+			delete(igc.NewReceivers, port)
+			receiversUpdated = true
+			if igp.Exclude {
+				igc.Exclude--
+			}
+		} else {
+			if igp, ok1 := igc.CurReceivers[port]; ok1 {
+				logger.Debug(ctx, "Deleting from CurReceivers")
+				delete(igc.CurReceivers, port)
+				receiversUpdated = true
+				if igp.Exclude {
+					igc.Exclude--
+				}
+			} else {
+				logger.Debug(ctx, "Receiver doesnot exist. Dropping Igmp leave")
+				return false
+			}
+		}
+		_ = db.DelIgmpRcvr(cntx, igc.Mvlan, igc.GroupAddr, igc.Device, port)
+	}
 
-        if igc.NumReceivers() == 0 {
-                igc.DelMcFlow(cntx)
-                mvp := GetApplication().GetMvlanProfileByTag(igc.Mvlan)
-                /* If proxy is configured and NumReceivers is 0, then we can reset the igc src list so that we send leave */
-                if _, ok := mvp.Proxy[igc.GroupName]; ok {
-                        igc.IncludeList = []net.IP{}
-                }
-                igc.SendLeaveToServer()
-                logger.Debugw(ctx, "Deleted the receiver Flow", log.Fields{"Num Receivers": igc.NumReceivers()})
-                return true
-        }
-        if groupModified {
-                igc.SendReport(false)
-                logger.Infow(ctx, "Updated SourceList for Channel", log.Fields{"Current": igc.CurReceivers, "New": igc.NewReceivers})
-        }
-        if err := igc.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
-        }
-        logger.Infow(ctx, "Updated Receiver info for Channel", log.Fields{"Current": igc.CurReceivers, "New": igc.NewReceivers})
+	if igc.NumReceivers() == 0 {
+		igc.DelMcFlow(cntx)
+		mvp := GetApplication().GetMvlanProfileByTag(igc.Mvlan)
+		/* If proxy is configured and NumReceivers is 0, then we can reset the igc src list so that we send leave */
+		if _, ok := mvp.Proxy[igc.GroupName]; ok {
+			igc.IncludeList = []net.IP{}
+		}
+		igc.SendLeaveToServer()
+		logger.Debugw(ctx, "Deleted the receiver Flow", log.Fields{"Num Receivers": igc.NumReceivers()})
+		return true
+	}
+	if groupModified {
+		igc.SendReport(false)
+		logger.Infow(ctx, "Updated SourceList for Channel", log.Fields{"Current": igc.CurReceivers, "New": igc.NewReceivers})
+	}
+	if err := igc.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
+	}
+	logger.Infow(ctx, "Updated Receiver info for Channel", log.Fields{"Current": igc.CurReceivers, "New": igc.NewReceivers})
 
-        return receiversUpdated
+	return receiversUpdated
 }
 
 // DelAllReceivers deletes all receiver for the provided igmp device
 func (igc *IgmpGroupChannel) DelAllReceivers(cntx context.Context) {
-        logger.Infow(ctx, "Deleting All Receiver for Channel", log.Fields{"Device": igc.Device, "Channel": igc.GroupAddr.String()})
-        _ = db.DelAllIgmpRcvr(cntx, igc.Mvlan, igc.GroupAddr, igc.Device)
-        igc.Exclude = 0
-        igc.DelMcFlow(cntx)
-        igc.SendLeaveToServer()
-        logger.Infow(ctx, "MC Flow deleted and Leave sent", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device})
+	logger.Infow(ctx, "Deleting All Receiver for Channel", log.Fields{"Device": igc.Device, "Channel": igc.GroupAddr.String()})
+	_ = db.DelAllIgmpRcvr(cntx, igc.Mvlan, igc.GroupAddr, igc.Device)
+	igc.Exclude = 0
+	igc.DelMcFlow(cntx)
+	igc.SendLeaveToServer()
+	logger.Infow(ctx, "MC Flow deleted and Leave sent", log.Fields{"Channel": igc.GroupAddr.String(), "Device": igc.Device})
 }
 
 // Igmpv2ReportPacket build an IGMPv2 Report for the upstream servers
 func (igc *IgmpGroupChannel) Igmpv2ReportPacket() ([]byte, error) {
-        logger.Debugw(ctx, "Buidling IGMP version 2 Report", log.Fields{"Device": igc.Device})
-        return IgmpReportv2Packet(igc.GroupAddr, igc.Mvlan, (*igc.proxyCfg).IgmpCos, **igc.IgmpProxyIP)
+	logger.Debugw(ctx, "Building IGMP version 2 Report", log.Fields{"Device": igc.Device})
+	return IgmpReportv2Packet(igc.GroupAddr, igc.Mvlan, (*igc.proxyCfg).IgmpCos, **igc.IgmpProxyIP)
 }
 
 // Igmpv3ReportPacket build an IGMPv3 Report for the upstream servers
 func (igc *IgmpGroupChannel) Igmpv3ReportPacket() ([]byte, error) {
-        logger.Debugw(ctx, "Buidling IGMP version 3 Report", log.Fields{"Device": igc.Device, "Exclude": igc.Exclude})
-        if igc.Exclude > 0 {
-                return Igmpv3ReportPacket(igc.GroupAddr, igc.Mvlan, (*igc.proxyCfg).IgmpCos, **igc.IgmpProxyIP, false, igc.ExcludeList)
-        }
-        return Igmpv3ReportPacket(igc.GroupAddr, igc.Mvlan, (*igc.proxyCfg).IgmpCos, **igc.IgmpProxyIP, true, igc.IncludeList)
+	logger.Debugw(ctx, "Building IGMP version 3 Report", log.Fields{"Device": igc.Device, "Exclude": igc.Exclude})
+	if igc.Exclude > 0 {
+		return Igmpv3ReportPacket(igc.GroupAddr, igc.Mvlan, (*igc.proxyCfg).IgmpCos, **igc.IgmpProxyIP, false, igc.ExcludeList)
+	}
+	return Igmpv3ReportPacket(igc.GroupAddr, igc.Mvlan, (*igc.proxyCfg).IgmpCos, **igc.IgmpProxyIP, true, igc.IncludeList)
 }
 
 // SendReport send a consolidated report to the server
 func (igc *IgmpGroupChannel) SendReport(isQuery bool) {
-        var report []byte
-        var err error
-        logger.Debugw(ctx, "Checking Version", log.Fields{"IGC Version": igc.Version, "Proxy Version": (*igc.proxyCfg).IgmpVerToServer,
-                "Result": (getVersion((*igc.proxyCfg).IgmpVerToServer) == IgmpVersion2)})
+	var report []byte
+	var err error
+	logger.Debugw(ctx, "Checking Version", log.Fields{"IGC Version": igc.Version, "Proxy Version": (*igc.proxyCfg).IgmpVerToServer,
+		"Result": (getVersion((*igc.proxyCfg).IgmpVerToServer) == IgmpVersion2)})
 
-        /**
-                                       +------------------------------------------------------------------------+
-                                       |         IGMP version(towards BNG) Configured at VGC                    |
-                                       +-------------------------------+----------------------------------------+
-                                       |                  v2           |                 v3                     |
-        +===================+==========+===============================+========================================+
-        | Received From RG  | V2 Join  | Process and Send as V2 to BNG | Process, Convert to v3 and Send to BNG |
-        |                   |          |                               | Process, Send as v2, if the BNG is v2  |
-        +===================+----------+-------------------------------+----------------------------------------+
-                            | V3 Join  | Process and Send as V2 to BNG | Process, Send v3 to BNG                |
-                            |          |                               | Process, Convert, Send as v2, if the   |
-                            |          |                               | BNG is v2                              |
-        +===================+==========+===============================+========================================+
-        | Received From BNG | V2 Query | V2 response to BNG            | V2 response to BNG                     |
-        +===================+----------+-------------------------------+----------------------------------------+
-                            | V3 Query | Discard                       | V3 response to BNG                     |
-                            +==========+===============================+========================================+
-        */
-        // igc.Version:         igmp version received from RG.
-        // igc.ServVersion: igmp version received from BNG or IgmpVerToServer present in proxy igmp conf.
+	/**
+	                                 +------------------------------------------------------------------------+
+	                                 |         IGMP version(towards BNG) Configured at VGC                    |
+	                                 +-------------------------------+----------------------------------------+
+	                                 |                  v2           |                 v3                     |
+	  +===================+==========+===============================+========================================+
+	  | Received From RG  | V2 Join  | Process and Send as V2 to BNG | Process, Convert to v3 and Send to BNG |
+	  |                   |          |                               | Process, Send as v2, if the BNG is v2  |
+	  +===================+----------+-------------------------------+----------------------------------------+
+	                      | V3 Join  | Process and Send as V2 to BNG | Process, Send v3 to BNG                |
+	                      |          |                               | Process, Convert, Send as v2, if the   |
+	                      |          |                               | BNG is v2                              |
+	  +===================+==========+===============================+========================================+
+	  | Received From BNG | V2 Query | V2 response to BNG            | V2 response to BNG                     |
+	  +===================+----------+-------------------------------+----------------------------------------+
+	                      | V3 Query | Discard                       | V3 response to BNG                     |
+	                      +==========+===============================+========================================+
+	*/
+	// igc.Version:         igmp version received from RG.
+	// igc.ServVersion: igmp version received from BNG or IgmpVerToServer present in proxy igmp conf.
 
-        if isQuery && *igc.ServVersion == IgmpVersion3 && getVersion((*igc.proxyCfg).IgmpVerToServer) == IgmpVersion2 {
-                // This is the last scenario where we must discard the query processing.
-                logger.Debug(ctx, "Dropping query packet since the server verion is v3 but igmp proxy version is v2")
-                return
-        }
+	if isQuery && *igc.ServVersion == IgmpVersion3 && getVersion((*igc.proxyCfg).IgmpVerToServer) == IgmpVersion2 {
+		// This is the last scenario where we must discard the query processing.
+		logger.Debug(ctx, "Dropping query packet since the server verion is v3 but igmp proxy version is v2")
+		return
+	}
 
-        if *igc.ServVersion == IgmpVersion2 || getVersion((*igc.proxyCfg).IgmpVerToServer) == IgmpVersion2 {
-                report, err = igc.Igmpv2ReportPacket()
-        } else {
-                report, err = igc.Igmpv3ReportPacket()
-        }
-        if err != nil {
-                logger.Warnw(ctx, "Error Preparing Report", log.Fields{"Device": igc.Device, "Ver": igc.Version, "Reason": err.Error()})
-                return
-        }
-        nni, err := GetApplication().GetNniPort(igc.Device)
-        if err == nil {
-                _ = cntlr.GetController().PacketOutReq(igc.Device, nni, nni, report, false)
-        } else {
-                logger.Warnw(ctx, "Didn't find NNI port", log.Fields{"Device": igc.Device})
-        }
+	if *igc.ServVersion == IgmpVersion2 || getVersion((*igc.proxyCfg).IgmpVerToServer) == IgmpVersion2 {
+		report, err = igc.Igmpv2ReportPacket()
+	} else {
+		report, err = igc.Igmpv3ReportPacket()
+	}
+	if err != nil {
+		logger.Warnw(ctx, "Error Preparing Report", log.Fields{"Device": igc.Device, "Ver": igc.Version, "Reason": err.Error()})
+		return
+	}
+	nni, err := GetApplication().GetNniPort(igc.Device)
+	if err == nil {
+		_ = cntlr.GetController().PacketOutReq(igc.Device, nni, nni, report, false)
+	} else {
+		logger.Warnw(ctx, "Didn't find NNI port", log.Fields{"Device": igc.Device})
+	}
 }
 
 // AddMcFlow adds flow to the device when the first receiver joins
 func (igc *IgmpGroupChannel) AddMcFlow(cntx context.Context) {
-        flow, err := igc.BuildMcFlow()
-        if err != nil {
-                logger.Warnw(ctx, "MC Flow Build Failed", log.Fields{"Reason": err.Error()})
-                return
-        }
-        port, _ := GetApplication().GetNniPort(igc.Device)
-        _ = cntlr.GetController().AddFlows(cntx, port, igc.Device, flow)
+	flow, err := igc.BuildMcFlow()
+	if err != nil {
+		logger.Warnw(ctx, "MC Flow Build Failed", log.Fields{"Reason": err.Error()})
+		return
+	}
+	port, _ := GetApplication().GetNniPort(igc.Device)
+	_ = cntlr.GetController().AddFlows(cntx, port, igc.Device, flow)
 }
 
 // DelMcFlow deletes flow from the device when the last receiver leaves
 func (igc *IgmpGroupChannel) DelMcFlow(cntx context.Context) {
-        flow, err := igc.BuildMcFlow()
-        if err != nil {
-                logger.Warnw(ctx, "MC Flow Build Failed", log.Fields{"Reason": err.Error()})
-                return
-        }
-        flow.ForceAction = true
-        device := GetApplication().GetDevice(igc.Device)
+	flow, err := igc.BuildMcFlow()
+	if err != nil {
+		logger.Warnw(ctx, "MC Flow Build Failed", log.Fields{"Reason": err.Error()})
+		return
+	}
+	flow.ForceAction = true
+	device := GetApplication().GetDevice(igc.Device)
 
-        if mvpIntf, _ := GetApplication().MvlanProfilesByTag.Load(igc.Mvlan); mvpIntf != nil {
-                mvp := mvpIntf.(*MvlanProfile)
-                err := mvp.DelFlows(cntx, device, flow)
-                if err != nil {
-                        logger.Warnw(ctx, "Delering IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
-                }
-        }
+	if mvpIntf, _ := GetApplication().MvlanProfilesByTag.Load(igc.Mvlan); mvpIntf != nil {
+		mvp := mvpIntf.(*MvlanProfile)
+		err := mvp.DelFlows(cntx, device, flow)
+		if err != nil {
+			logger.Warnw(ctx, "Delering IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
+		}
+	}
 }
 
 // BuildMcFlow builds the flow using which it is added/deleted
 func (igc *IgmpGroupChannel) BuildMcFlow() (*of.VoltFlow, error) {
-        flow := &of.VoltFlow{}
-        flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
-        //va := GetApplication()
-        logger.Infow(ctx, "Building Mcast flow", log.Fields{"Mcast Group": igc.GroupAddr.String(), "Mvlan": igc.Mvlan.String()})
-        uintGroupAddr := ipv4ToUint(igc.GroupAddr)
-        subFlow := of.NewVoltSubFlow()
-        subFlow.SetMatchVlan(igc.Mvlan)
-        subFlow.SetIpv4Match()
-        subFlow.SetMatchDstIpv4(igc.GroupAddr)
-        mvp := GetApplication().GetMvlanProfileByTag(igc.Mvlan)
-        //nni, err := va.GetNniPort(igc.Device)
-        //if err != nil {
-        //      return nil, err
-        //}
-        //inport, err := va.GetPortID(nni)
-        //if err != nil {
-        //      return nil, err
-        //}
-        //subFlow.SetInPort(inport)
-        subFlow.SetOutGroup(igc.GroupID)
-        cookiePort := uintGroupAddr
-        subFlow.Cookie = uint64(cookiePort)<<32 | uint64(igc.Mvlan)
-        subFlow.Priority = of.McFlowPriority
-        metadata := uint64(mvp.PonVlan)
-        subFlow.SetTableMetadata(metadata)
+	flow := &of.VoltFlow{}
+	flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
+	//va := GetApplication()
+	logger.Infow(ctx, "Building Mcast flow", log.Fields{"Mcast Group": igc.GroupAddr.String(), "Mvlan": igc.Mvlan.String()})
+	uintGroupAddr := ipv4ToUint(igc.GroupAddr)
+	subFlow := of.NewVoltSubFlow()
+	subFlow.SetMatchVlan(igc.Mvlan)
+	subFlow.SetIpv4Match()
+	subFlow.SetMatchDstIpv4(igc.GroupAddr)
+	mvp := GetApplication().GetMvlanProfileByTag(igc.Mvlan)
+	//nni, err := va.GetNniPort(igc.Device)
+	//if err != nil {
+	//      return nil, err
+	//}
+	//inport, err := va.GetPortID(nni)
+	//if err != nil {
+	//      return nil, err
+	//}
+	//subFlow.SetInPort(inport)
+	subFlow.SetOutGroup(igc.GroupID)
+	cookiePort := uintGroupAddr
+	subFlow.Cookie = uint64(cookiePort)<<32 | uint64(igc.Mvlan)
+	subFlow.Priority = of.McFlowPriority
+	metadata := uint64(mvp.PonVlan)
+	subFlow.SetTableMetadata(metadata)
 
-        flow.SubFlows[subFlow.Cookie] = subFlow
-        logger.Infow(ctx, "Built Mcast flow", log.Fields{"cookie": subFlow.Cookie, "subflow": subFlow})
-        return flow, nil
+	flow.SubFlows[subFlow.Cookie] = subFlow
+	logger.Infow(ctx, "Built Mcast flow", log.Fields{"cookie": subFlow.Cookie, "subflow": subFlow})
+	return flow, nil
 }
 
 // IgmpLeaveToServer sends IGMP leave to server. Called when the last receiver leaves the group
 func (igc *IgmpGroupChannel) IgmpLeaveToServer() {
-        if leave, err := IgmpLeavePacket(igc.GroupAddr, igc.Mvlan, (*igc.proxyCfg).IgmpCos, **igc.IgmpProxyIP); err == nil {
-                nni, err1 := GetApplication().GetNniPort(igc.Device)
-                if err1 == nil {
-                        _ = cntlr.GetController().PacketOutReq(igc.Device, nni, nni, leave, false)
-                }
-        }
+	if leave, err := IgmpLeavePacket(igc.GroupAddr, igc.Mvlan, (*igc.proxyCfg).IgmpCos, **igc.IgmpProxyIP); err == nil {
+		nni, err1 := GetApplication().GetNniPort(igc.Device)
+		if err1 == nil {
+			_ = cntlr.GetController().PacketOutReq(igc.Device, nni, nni, leave, false)
+		}
+	}
 }
 
 // SendLeaveToServer delete the group when the last receiver leaves the group
 func (igc *IgmpGroupChannel) SendLeaveToServer() {
-        /**
-                                       +-------------------------------------------------------------------------+
-                                       |         IGMP version(towards BNG) Configured at VGC                     |
-                                       +-------------------------------+-----------------------------------------+
-                                       |                  v2           |                 v3                      |
-        +===================+==========+===============================+=========================================+
-        | Received From RG  | V2 Leave | Process and Send as V2 to BNG | Process, Convert to V3 and Send to BNG/ |
-        |                   |          |                               | Process, Send as V2, if the BNG is V2   |
-        +===================+----------+-------------------------------+-----------------------------------------+
-                            | V3 Leave | Process and Send as V2 to BNG | Process, Send V3 to BNG                 |
-                            |          |                               | Process, Convert, Send as V2, if the    |
-                            |          |                               | BNG is v2                               |
-                            +==========+===============================+=========================================+
-        */
-        // igc.Version:         igmp version received from RG.
-        // igc.ServVersion: igmp version received from BNG or IgmpVerToServer present in proxy igmp conf.
+	/**
+	                                 +-------------------------------------------------------------------------+
+	                                 |         IGMP version(towards BNG) Configured at VGC                     |
+	                                 +-------------------------------+-----------------------------------------+
+	                                 |                  v2           |                 v3                      |
+	  +===================+==========+===============================+=========================================+
+	  | Received From RG  | V2 Leave | Process and Send as V2 to BNG | Process, Convert to V3 and Send to BNG/ |
+	  |                   |          |                               | Process, Send as V2, if the BNG is V2   |
+	  +===================+----------+-------------------------------+-----------------------------------------+
+	                      | V3 Leave | Process and Send as V2 to BNG | Process, Send V3 to BNG                 |
+	                      |          |                               | Process, Convert, Send as V2, if the    |
+	                      |          |                               | BNG is v2                               |
+	                      +==========+===============================+=========================================+
+	*/
+	// igc.Version:         igmp version received from RG.
+	// igc.ServVersion: igmp version received from BNG or IgmpVerToServer present in proxy igmp conf.
 
-        logger.Debugw(ctx, "Sending IGMP leave upstream", log.Fields{"Device": igc.Device})
-        if *igc.ServVersion == IgmpVersion2 || getVersion((*igc.proxyCfg).IgmpVerToServer) == IgmpVersion2 {
-                igc.IgmpLeaveToServer()
-        } else {
-                igc.SendReport(false)
-        }
+	logger.Debugw(ctx, "Sending IGMP leave upstream", log.Fields{"Device": igc.Device})
+	if *igc.ServVersion == IgmpVersion2 || getVersion((*igc.proxyCfg).IgmpVerToServer) == IgmpVersion2 {
+		igc.IgmpLeaveToServer()
+	} else {
+		igc.SendReport(false)
+	}
 }
 
 // NumReceivers returns total number of receivers left on the group
 func (igc *IgmpGroupChannel) NumReceivers() uint32 {
-        return uint32(len(igc.CurReceivers) + len(igc.NewReceivers))
+	return uint32(len(igc.CurReceivers) + len(igc.NewReceivers))
 }
 
 // SendQuery sends query to the receivers for counting purpose
 func (igc *IgmpGroupChannel) SendQuery() {
-        //var b []byte
-        //var err error
-        for portKey, port := range igc.NewReceivers {
-                igc.CurReceivers[portKey] = port
-        }
+	//var b []byte
+	//var err error
+	for portKey, port := range igc.NewReceivers {
+		igc.CurReceivers[portKey] = port
+	}
 
-        igc.NewReceivers = make(map[string]*IgmpGroupPort)
+	igc.NewReceivers = make(map[string]*IgmpGroupPort)
 
-        logger.Debugw(ctx, "Sending Query to receivers", log.Fields{"Receivers": igc.CurReceivers})
-        for port, groupPort := range igc.CurReceivers {
-                if port == StaticPort {
-                        continue
-                }
-                if queryPkt, err := igc.buildQuery(igc.GroupAddr, of.VlanType(groupPort.CVlan), groupPort.Pbit); err == nil {
-                        _ = cntlr.GetController().PacketOutReq(igc.Device, port, port, queryPkt, false)
-                        logger.Debugw(ctx, "Query Sent", log.Fields{"Device": igc.Device, "Port": port, "Packet": queryPkt})
-                } else {
-                        logger.Warnw(ctx, "Query Creation Failed", log.Fields{"Reason": err.Error()})
-                }
-        }
-
+	logger.Debugw(ctx, "Sending Query to receivers", log.Fields{"Receivers": igc.CurReceivers})
+	for port, groupPort := range igc.CurReceivers {
+		if port == StaticPort {
+			continue
+		}
+		if queryPkt, err := igc.buildQuery(igc.GroupAddr, of.VlanType(groupPort.CVlan), groupPort.Pbit); err == nil {
+			_ = cntlr.GetController().PacketOutReq(igc.Device, port, port, queryPkt, false)
+			logger.Debugw(ctx, "Query Sent", log.Fields{"Device": igc.Device, "Port": port, "Packet": queryPkt})
+		} else {
+			logger.Warnw(ctx, "Query Creation Failed", log.Fields{"Reason": err.Error()})
+		}
+	}
 }
 
 // buildQuery to build query packet
 func (igc *IgmpGroupChannel) buildQuery(groupAddr net.IP, cVlan of.VlanType, pbit uint8) ([]byte, error) {
-        if igc.Version == IgmpVersion2 {
-                return Igmpv2QueryPacket(igc.GroupAddr, cVlan, **igc.IgmpProxyIP, pbit, (*igc.proxyCfg).MaxResp)
-        }
-        return Igmpv3QueryPacket(igc.GroupAddr, cVlan, **igc.IgmpProxyIP, pbit, (*igc.proxyCfg).MaxResp)
+	if igc.Version == IgmpVersion2 {
+		return Igmpv2QueryPacket(igc.GroupAddr, cVlan, **igc.IgmpProxyIP, pbit, (*igc.proxyCfg).MaxResp)
+	}
+	return Igmpv3QueryPacket(igc.GroupAddr, cVlan, **igc.IgmpProxyIP, pbit, (*igc.proxyCfg).MaxResp)
 }
 
 // ProcessMode process the received mode and updated the igp
 func (igc *IgmpGroupChannel) ProcessMode(port string, incl bool) {
-        /* Update the mode in igp if the mode has changed */
-        igp := igc.GetReceiver(port)
-        if igp.Exclude && incl {
-                igp.Exclude = !incl
-                if igc.Exclude > 0 {
-                        igc.Exclude--
-                }
-        } else if !incl && !igp.Exclude {
-                igp.Exclude = !incl
-                igc.Exclude++
-        }
+	/* Update the mode in igp if the mode has changed */
+	igp := igc.GetReceiver(port)
+	if igp.Exclude && incl {
+		igp.Exclude = !incl
+		if igc.Exclude > 0 {
+			igc.Exclude--
+		}
+	} else if !incl && !igp.Exclude {
+		igp.Exclude = !incl
+		igc.Exclude++
+	}
 }
-
diff --git a/internal/pkg/application/igmpgroupdevice.go b/internal/pkg/application/igmpgroupdevice.go
index 0d59747..1a12bc4 100644
--- a/internal/pkg/application/igmpgroupdevice.go
+++ b/internal/pkg/application/igmpgroupdevice.go
@@ -11,7 +11,7 @@
 * 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 application
 
@@ -36,492 +36,475 @@
 // report when the first listener joins and is responsible for
 // sending responses to upstream queries
 type IgmpGroupDevice struct {
-        Device            string
-        SerialNo          string
-        GroupID           uint32
-        GroupName         string
-        GroupAddr         net.IP
-        RecvVersion       uint8
-        ServVersion       *uint8
-        RecvVersionExpiry time.Time
-        ServVersionExpiry time.Time
-        Mvlan             of.VlanType
-        PonVlan           of.VlanType
-        IsPonVlanPresent  bool
-        GroupInstalled    bool
-        GroupChannels     sync.Map            `json:"-"` // [ipAddr]*IgmpGroupChannel
-        PortChannelMap    sync.Map            `json:"-"` // [portName][]net.IP
-        PonPortChannelMap *util.ConcurrentMap `json:"-"` // [ponPortId]*PonPortChannels
-        proxyCfg          *IgmpProfile                   // IgmpSrcIp from IgmpProfile is not used, it is kept for backward compatibility
-        IgmpProxyIP       *net.IP             `json:"-"`
-        NextQueryTime     time.Time
-        QueryExpiryTime   time.Time
+	PonPortChannelMap *util.ConcurrentMap `json:"-"` // [ponPortId]*PonPortChannels
+	proxyCfg          *IgmpProfile        // IgmpSrcIp from IgmpProfile is not used, it is kept for backward compatibility
+	IgmpProxyIP       *net.IP             `json:"-"`
+	ServVersion       *uint8
+	Device            string
+	SerialNo          string
+	GroupName         string
+	GroupChannels     sync.Map `json:"-"` // [ipAddr]*IgmpGroupChannel
+	PortChannelMap    sync.Map `json:"-"` // [portName][]net.IP
+	NextQueryTime     time.Time
+	QueryExpiryTime   time.Time
+	RecvVersionExpiry time.Time
+	ServVersionExpiry time.Time
+	GroupAddr         net.IP
+	GroupID           uint32
+	Mvlan             of.VlanType
+	PonVlan           of.VlanType
+	RecvVersion       uint8
+	IsPonVlanPresent  bool
+	GroupInstalled    bool
 }
 
 // NewIgmpGroupDevice is constructor for a device. The default IGMP version is set to 3
 // as the protocol defines the way to manage backward compatibility
-// The implementation handles simultaneous presense of lower versioned
+// The implementation handles simultaneous presence of lower versioned
 // receivers
 func NewIgmpGroupDevice(name string, ig *IgmpGroup, id uint32, version uint8) *IgmpGroupDevice {
-        var igd IgmpGroupDevice
-        igd.Device = name
-        igd.GroupID = id
-        igd.GroupName = ig.GroupName
-        igd.GroupAddr = ig.GroupAddr
-        igd.Mvlan = ig.Mvlan
-        igd.PonVlan = ig.PonVlan
-        igd.IsPonVlanPresent = ig.IsPonVlanPresent
-        igd.GroupInstalled = false
-        igd.RecvVersion = version
-        igd.RecvVersionExpiry = time.Now()
-        igd.ServVersionExpiry = time.Now()
-        igd.PonPortChannelMap = util.NewConcurrentMap()
+	var igd IgmpGroupDevice
+	igd.Device = name
+	igd.GroupID = id
+	igd.GroupName = ig.GroupName
+	igd.GroupAddr = ig.GroupAddr
+	igd.Mvlan = ig.Mvlan
+	igd.PonVlan = ig.PonVlan
+	igd.IsPonVlanPresent = ig.IsPonVlanPresent
+	igd.GroupInstalled = false
+	igd.RecvVersion = version
+	igd.RecvVersionExpiry = time.Now()
+	igd.ServVersionExpiry = time.Now()
+	igd.PonPortChannelMap = util.NewConcurrentMap()
 
-        va := GetApplication()
-        if vd := va.GetDevice(igd.Device); vd != nil {
-                igd.SerialNo = vd.SerialNum
-        } else {
-                logger.Errorw(ctx, "Volt Device not found.  log.Fields", log.Fields{"igd.Device": igd.Device})
-                return nil
-        }
-        mvp := GetApplication().GetMvlanProfileByTag(igd.Mvlan)
-        igd.ServVersion = mvp.IgmpServVersion[igd.SerialNo]
+	va := GetApplication()
+	if vd := va.GetDevice(igd.Device); vd != nil {
+		igd.SerialNo = vd.SerialNum
+	} else {
+		logger.Errorw(ctx, "Volt Device not found.  log.Fields", log.Fields{"igd.Device": igd.Device})
+		return nil
+	}
+	mvp := GetApplication().GetMvlanProfileByTag(igd.Mvlan)
+	igd.ServVersion = mvp.IgmpServVersion[igd.SerialNo]
 
-        var mcastCfg *McastConfig
-        igd.proxyCfg, igd.IgmpProxyIP, mcastCfg = getIgmpProxyCfgAndIP(ig.Mvlan, igd.SerialNo)
+	var mcastCfg *McastConfig
+	igd.proxyCfg, igd.IgmpProxyIP, mcastCfg = getIgmpProxyCfgAndIP(ig.Mvlan, igd.SerialNo)
 
-        // mvlan profile id + olt serial number---igmp group id
-        //igmpgroup id
-        igd.NextQueryTime = time.Now().Add(time.Duration(igd.proxyCfg.KeepAliveInterval) * time.Second)
-        igd.QueryExpiryTime = time.Now().Add(time.Duration(igd.proxyCfg.KeepAliveInterval) * time.Second)
+	// mvlan profile id + olt serial number---igmp group id
+	//igmpgroup id
+	igd.NextQueryTime = time.Now().Add(time.Duration(igd.proxyCfg.KeepAliveInterval) * time.Second)
+	igd.QueryExpiryTime = time.Now().Add(time.Duration(igd.proxyCfg.KeepAliveInterval) * time.Second)
 
-        if mcastCfg != nil {
-                mcastCfg.IgmpGroupDevices.Store(id, &igd)
-                logger.Debugw(ctx, "Igd added to mcast config", log.Fields{"mvlan": mcastCfg.MvlanProfileID, "groupId": id})
-        }
-        return &igd
+	if mcastCfg != nil {
+		mcastCfg.IgmpGroupDevices.Store(id, &igd)
+		logger.Debugw(ctx, "Igd added to mcast config", log.Fields{"mvlan": mcastCfg.MvlanProfileID, "groupId": id})
+	}
+	return &igd
 }
 
 // IgmpGroupDeviceReInit is re-initializer for a device. The default IGMP version is set to 3
 // as the protocol defines the way to manage backward compatibility
 func (igd *IgmpGroupDevice) IgmpGroupDeviceReInit(cntx context.Context, ig *IgmpGroup) {
+	logger.Infow(ctx, "Reinitialize Igmp Group Device", log.Fields{"Device": igd.Device, "GroupID": ig.GroupID, "OldName": igd.GroupName, "Name": ig.GroupName, "OldAddr": igd.GroupAddr.String(), "GroupAddr": ig.GroupAddr.String()})
 
-        logger.Infow(ctx, "Reinitialize Igmp Group Device", log.Fields{"Device": igd.Device, "GroupID": ig.GroupID, "OldName": igd.GroupName, "Name": ig.GroupName, "OldAddr": igd.GroupAddr.String(), "GroupAddr": ig.GroupAddr.String()})
+	if (igd.GroupName != ig.GroupName) || !igd.GroupAddr.Equal(ig.GroupAddr) {
+		_ = db.DelIgmpDevice(cntx, igd.Mvlan, igd.GroupName, igd.GroupAddr, igd.Device)
+		igd.GroupName = ig.GroupName
+		igd.GroupAddr = ig.GroupAddr
+	}
+	igd.RecvVersionExpiry = time.Now()
+	igd.ServVersionExpiry = time.Now()
+	igd.PonPortChannelMap = util.NewConcurrentMap()
 
-        if (igd.GroupName != ig.GroupName) || !igd.GroupAddr.Equal(ig.GroupAddr) {
-                _ = db.DelIgmpDevice(cntx, igd.Mvlan, igd.GroupName, igd.GroupAddr, igd.Device)
-                igd.GroupName = ig.GroupName
-                igd.GroupAddr = ig.GroupAddr
-        }
-        igd.RecvVersionExpiry = time.Now()
-        igd.ServVersionExpiry = time.Now()
-        igd.PonPortChannelMap = util.NewConcurrentMap()
+	var mcastCfg *McastConfig
+	igd.proxyCfg, igd.IgmpProxyIP, mcastCfg = getIgmpProxyCfgAndIP(ig.Mvlan, igd.SerialNo)
 
-        var mcastCfg *McastConfig
-        igd.proxyCfg, igd.IgmpProxyIP, mcastCfg = getIgmpProxyCfgAndIP(ig.Mvlan, igd.SerialNo)
+	igd.NextQueryTime = time.Now().Add(time.Duration(igd.proxyCfg.KeepAliveInterval) * time.Second)
+	igd.QueryExpiryTime = time.Now().Add(time.Duration(igd.proxyCfg.KeepAliveInterval) * time.Second)
 
-        igd.NextQueryTime = time.Now().Add(time.Duration(igd.proxyCfg.KeepAliveInterval) * time.Second)
-        igd.QueryExpiryTime = time.Now().Add(time.Duration(igd.proxyCfg.KeepAliveInterval) * time.Second)
-
-        if mcastCfg != nil {
-                mcastCfg.IgmpGroupDevices.Store(ig.GroupID, igd)
-                logger.Debugw(ctx, "Igd added to mcast config", log.Fields{"mvlan": mcastCfg.MvlanProfileID, "groupId": ig.GroupID})
-        }
-        if err := igd.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
-        }
+	if mcastCfg != nil {
+		mcastCfg.IgmpGroupDevices.Store(ig.GroupID, igd)
+		logger.Debugw(ctx, "Igd added to mcast config", log.Fields{"mvlan": mcastCfg.MvlanProfileID, "groupId": ig.GroupID})
+	}
+	if err := igd.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
+	}
 }
 
 func getIgmpProxyCfgAndIP(mvlan of.VlanType, serialNo string) (*IgmpProfile, *net.IP, *McastConfig) {
-        va := GetApplication()
-        mVLANProfileID := va.GetMvlanProfileByTag(mvlan).Name
-        var mcastCfg *McastConfig
-        if mcastCfg = va.GetMcastConfig(serialNo, mVLANProfileID); mcastCfg == nil || (mcastCfg != nil && mcastCfg.IgmpProfileID == "") {
-                logger.Debugw(ctx, "Default IGMP config to be used", log.Fields{"mVLANProfileID": mVLANProfileID, "OltSerialNo": serialNo})
-                igmpProf := va.getIgmpProfileMap(DefaultIgmpProfID)
-                return igmpProf, &igmpProf.IgmpSourceIP, mcastCfg
-        }
-        return va.getIgmpProfileMap(mcastCfg.IgmpProfileID), &mcastCfg.IgmpProxyIP, mcastCfg
+	va := GetApplication()
+	mVLANProfileID := va.GetMvlanProfileByTag(mvlan).Name
+	var mcastCfg *McastConfig
+	if mcastCfg = va.GetMcastConfig(serialNo, mVLANProfileID); mcastCfg == nil || (mcastCfg != nil && mcastCfg.IgmpProfileID == "") {
+		logger.Debugw(ctx, "Default IGMP config to be used", log.Fields{"mVLANProfileID": mVLANProfileID, "OltSerialNo": serialNo})
+		igmpProf := va.getIgmpProfileMap(DefaultIgmpProfID)
+		return igmpProf, &igmpProf.IgmpSourceIP, mcastCfg
+	}
+	return va.getIgmpProfileMap(mcastCfg.IgmpProfileID), &mcastCfg.IgmpProxyIP, mcastCfg
 }
 
 // updateGroupName to update the group name
 func (igd *IgmpGroupDevice) updateGroupName(cntx context.Context, newGroupName string) {
-
-        oldName := igd.GroupName
-        igd.GroupName = newGroupName
-        updateGroupName := func(key, value interface{}) bool {
-                igc := value.(*IgmpGroupChannel)
-                igc.GroupName = newGroupName
-                if err := igc.WriteToDb(cntx); err != nil {
-                        logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
-                }
-                _ = db.DelIgmpChannel(cntx, igc.Mvlan, oldName, igc.Device, igc.GroupAddr)
-                return true
-        }
-        igd.GroupChannels.Range(updateGroupName)
-        if err := igd.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
-        }
-        _ = db.DelIgmpDevice(cntx, igd.Mvlan, oldName, igd.GroupAddr, igd.Device)
+	oldName := igd.GroupName
+	igd.GroupName = newGroupName
+	updateGroupName := func(key, value interface{}) bool {
+		igc := value.(*IgmpGroupChannel)
+		igc.GroupName = newGroupName
+		if err := igc.WriteToDb(cntx); err != nil {
+			logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
+		}
+		_ = db.DelIgmpChannel(cntx, igc.Mvlan, oldName, igc.Device, igc.GroupAddr)
+		return true
+	}
+	igd.GroupChannels.Range(updateGroupName)
+	if err := igd.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
+	}
+	_ = db.DelIgmpDevice(cntx, igd.Mvlan, oldName, igd.GroupAddr, igd.Device)
 }
 
 // NewIgmpGroupDeviceFromBytes is to create the IGMP group port from a byte slice
 func NewIgmpGroupDeviceFromBytes(b []byte) (*IgmpGroupDevice, error) {
-        var igd IgmpGroupDevice
-        if err := json.Unmarshal(b, &igd); err != nil {
-                return nil, err
-        }
-        return &igd, nil
+	var igd IgmpGroupDevice
+	if err := json.Unmarshal(b, &igd); err != nil {
+		return nil, err
+	}
+	return &igd, nil
 }
 
 // GetKey to get group name as key
 func (igd *IgmpGroupDevice) GetKey() string {
-
-        if !net.ParseIP("0.0.0.0").Equal(igd.GroupAddr) {
-                return igd.GroupName + "_" + igd.GroupAddr.String()
-        }
-        return igd.GroupName
-
+	if !net.ParseIP("0.0.0.0").Equal(igd.GroupAddr) {
+		return igd.GroupName + "_" + igd.GroupAddr.String()
+	}
+	return igd.GroupName
 }
 
 // RestoreChannel to restore channel
 func (igd *IgmpGroupDevice) RestoreChannel(cntx context.Context, igmpGroupChannel []byte) {
+	if igc, err := NewIgmpGroupChannelFromBytes(igmpGroupChannel); err == nil {
+		igc.ServVersion = igd.ServVersion
+		igc.IgmpProxyIP = &igd.IgmpProxyIP
+		igc.proxyCfg = &igd.proxyCfg
+		igd.GroupChannels.Store(igc.GroupAddr.String(), igc)
+		igc.RestorePorts(cntx)
 
-        if igc, err := NewIgmpGroupChannelFromBytes(igmpGroupChannel); err == nil {
-                igc.ServVersion = igd.ServVersion
-                igc.IgmpProxyIP = &igd.IgmpProxyIP
-                igc.proxyCfg = &igd.proxyCfg
-                igd.GroupChannels.Store(igc.GroupAddr.String(), igc)
-                igc.RestorePorts(cntx)
+		for port, igp := range igc.NewReceivers {
+			ipsList := []net.IP{}
+			ipsIntf, _ := igd.PortChannelMap.Load(port)
+			if ipsIntf != nil {
+				ipsList = ipsIntf.([]net.IP)
+			}
 
-                for port, igp := range igc.NewReceivers {
-                        ipsList := []net.IP{}
-                        ipsIntf, _ := igd.PortChannelMap.Load(port)
-                        if ipsIntf != nil {
-                                ipsList = ipsIntf.([]net.IP)
-                        }
-
-                        ipsList = append(ipsList, igc.GroupAddr)
-                        igd.PortChannelMap.Store(port, ipsList)
-                        logger.Infow(ctx, "Group Channels Restored", log.Fields{"IGC": igc})
-                        igd.AddChannelToChannelsPerPon(port, igc.GroupAddr, igp.PonPortID)
-                }
-        } else {
-                logger.Warnw(ctx, "Failed to decode port from DB", log.Fields{"err": err})
-        }
-        logger.Info(ctx, "Group Device & Channels Restored")
-        igd.PortChannelMap.Range(printPortChannel)
-        igd.GroupChannels.Range(printChannel)
-
+			ipsList = append(ipsList, igc.GroupAddr)
+			igd.PortChannelMap.Store(port, ipsList)
+			logger.Infow(ctx, "Group Channels Restored", log.Fields{"IGC": igc})
+			igd.AddChannelToChannelsPerPon(port, igc.GroupAddr, igp.PonPortID)
+		}
+	} else {
+		logger.Warnw(ctx, "Failed to decode port from DB", log.Fields{"err": err})
+	}
+	logger.Info(ctx, "Group Device & Channels Restored")
+	igd.PortChannelMap.Range(printPortChannel)
+	igd.GroupChannels.Range(printChannel)
 }
 
 // RestoreChannels to restore channels
 func (igd *IgmpGroupDevice) RestoreChannels(cntx context.Context) {
-
-        igd.migrateIgmpChannels(cntx)
-        channels, _ := db.GetIgmpChannels(cntx, igd.Mvlan, igd.GroupName, igd.Device)
-        for _, channel := range channels {
-
-                b, ok := channel.Value.([]byte)
-                if !ok {
-                        logger.Warn(ctx, "The value type is not []byte")
-                        continue
-                }
-                igd.RestoreChannel(cntx, b)
-        }
-
+	igd.migrateIgmpChannels(cntx)
+	channels, _ := db.GetIgmpChannels(cntx, igd.Mvlan, igd.GroupName, igd.Device)
+	for _, channel := range channels {
+		b, ok := channel.Value.([]byte)
+		if !ok {
+			logger.Warn(ctx, "The value type is not []byte")
+			continue
+		}
+		igd.RestoreChannel(cntx, b)
+	}
 }
 
-
 // WriteToDb is utility to write IGMP Group Device Info to the database
 func (igd *IgmpGroupDevice) WriteToDb(cntx context.Context) error {
-        b, err := json.Marshal(igd)
-        if err != nil {
-                return err
-        }
-        if err1 := db.PutIgmpDevice(cntx, igd.Mvlan, igd.GroupName, igd.GroupAddr, igd.Device, string(b)); err1 != nil {
-                return err1
-        }
-        logger.Info(ctx, "IGD Updated")
-        return nil
+	b, err := json.Marshal(igd)
+	if err != nil {
+		return err
+	}
+	if err1 := db.PutIgmpDevice(cntx, igd.Mvlan, igd.GroupName, igd.GroupAddr, igd.Device, string(b)); err1 != nil {
+		return err1
+	}
+	logger.Info(ctx, "IGD Updated")
+	return nil
 }
 
 // Tick processes timing tick used to run timers within the device
 func (igd *IgmpGroupDevice) Tick() uint8 {
-        /* Not using RecvVersionExpiry as it is not used anywhere
-        if time.Now().After(igd.RecvVersionExpiry) {
-                igd.RecvVersion = IgmpVersion3
-                return true
-        }
-        */
-        return 0
+	/* Not using RecvVersionExpiry as it is not used anywhere
+	   if time.Now().After(igd.RecvVersionExpiry) {
+	           igd.RecvVersion = IgmpVersion3
+	           return true
+	   }
+	*/
+	return 0
 }
 
 // GetSubscriberCountForChannelAndPonPort Gets the active subscriber count
 // for the given channel for one particular PON port
 func (igd *IgmpGroupDevice) GetSubscriberCountForChannelAndPonPort(ponPortID uint32, channelIP net.IP) uint64 {
-        if portMapIntf, ok := igd.PonPortChannelMap.Get(ponPortID); ok {
-                portChannelMap := portMapIntf.(*PonPortChannels)
+	if portMapIntf, ok := igd.PonPortChannelMap.Get(ponPortID); ok {
+		portChannelMap := portMapIntf.(*PonPortChannels)
 
-                if channel, present := portChannelMap.ChannelList.Get(channelIP.String()); present {
-                        return channel.(*UniPortList).UNIList.Length()
-                }
-        } else {
-                logger.Warnw(ctx, "PON port not found in PortChannelMap", log.Fields{"PON": ponPortID, "channel": channelIP})
-        }
-        return 0
+		if channel, present := portChannelMap.ChannelList.Get(channelIP.String()); present {
+			return channel.(*UniPortList).UNIList.Length()
+		}
+	} else {
+		logger.Warnw(ctx, "PON port not found in PortChannelMap", log.Fields{"PON": ponPortID, "channel": channelIP})
+	}
+	return 0
 }
 
 // AddChannelToChannelsPerPon Adds the new channel into the per Pon channel list
 func (igd *IgmpGroupDevice) AddChannelToChannelsPerPon(uniPort string, channelIP net.IP, ponPortID uint32) bool {
-        logger.Debugw(ctx, "Adding channel to ActiveChannelsPerPon list", log.Fields{"PonPort": ponPortID, "channelIP": channelIP})
+	logger.Debugw(ctx, "Adding channel to ActiveChannelsPerPon list", log.Fields{"PonPort": ponPortID, "channelIP": channelIP})
 
-        isNewChannel := bool(false)
-        isNewReceiver := false
-        if port, ok := igd.PonPortChannelMap.Get(ponPortID); !ok {
-                // PON port not exists in igd. adding it.
-                isNewReceiver = true
-                ponPortChannels := NewPonPortChannels()
-                isNewChannel = ponPortChannels.AddChannelToMap(uniPort, channelIP.String())
-                igd.PonPortChannelMap.Set(ponPortID, ponPortChannels)
-        } else {
-                // PON port exists in igd. Appending the channel list
-                // in the PON port.
-                isNewChannel = port.(*PonPortChannels).AddChannelToMap(uniPort, channelIP.String())
-                igd.PonPortChannelMap.Set(ponPortID, port)
-                count := port.(*PonPortChannels).GetActiveChannelCount()
+	isNewChannel := bool(false)
+	isNewReceiver := false
+	if port, ok := igd.PonPortChannelMap.Get(ponPortID); !ok {
+		// PON port not exists in igd. adding it.
+		isNewReceiver = true
+		ponPortChannels := NewPonPortChannels()
+		isNewChannel = ponPortChannels.AddChannelToMap(uniPort, channelIP.String())
+		igd.PonPortChannelMap.Set(ponPortID, ponPortChannels)
+	} else {
+		// PON port exists in igd. Appending the channel list
+		// in the PON port.
+		isNewChannel = port.(*PonPortChannels).AddChannelToMap(uniPort, channelIP.String())
+		igd.PonPortChannelMap.Set(ponPortID, port)
+		count := port.(*PonPortChannels).GetActiveChannelCount()
 
-                logger.Debugw(ctx, "activeChannelCount", log.Fields{"count": count})
-        }
-        GetApplication().UpdateActiveChannelCountForPonPort(igd.Device, uniPort, ponPortID, true, isNewChannel, igd)
-        return isNewReceiver
+		logger.Debugw(ctx, "activeChannelCount", log.Fields{"count": count})
+	}
+	GetApplication().UpdateActiveChannelCountForPonPort(igd.Device, uniPort, ponPortID, true, isNewChannel, igd)
+	return isNewReceiver
 }
 
 // RemoveChannelFromChannelsPerPon removes the channel from the per pon channel list.
 func (igd *IgmpGroupDevice) RemoveChannelFromChannelsPerPon(uniPort string, channelIP net.IP, ponPortID uint32) bool {
-        logger.Debugw(ctx, "Removing channel from ActiveChannelsPerPon list", log.Fields{"PonPort": ponPortID, "channelIP": channelIP})
-        var deleted bool
-        ponRemoved := false
+	logger.Debugw(ctx, "Removing channel from ActiveChannelsPerPon list", log.Fields{"PonPort": ponPortID, "channelIP": channelIP})
+	var deleted bool
+	ponRemoved := false
 
-        if port, ok := igd.PonPortChannelMap.Get(ponPortID); ok {
-                channelPortMap := port.(*PonPortChannels)
-                deleted = channelPortMap.RemoveChannelFromMap(uniPort, channelIP.String())
-                if deleted && channelPortMap.ChannelList.Length() == 0 {
-                        igd.PonPortChannelMap.Remove(ponPortID)
-                        ponRemoved = true
-                }
-                GetApplication().UpdateActiveChannelCountForPonPort(igd.Device, uniPort, ponPortID, false, deleted, igd)
-        } else {
-                logger.Warnw(ctx, "PON port doesn't exists in the igd", log.Fields{"PonPortID": ponPortID})
-        }
-        return ponRemoved
+	if port, ok := igd.PonPortChannelMap.Get(ponPortID); ok {
+		channelPortMap := port.(*PonPortChannels)
+		deleted = channelPortMap.RemoveChannelFromMap(uniPort, channelIP.String())
+		if deleted && channelPortMap.ChannelList.Length() == 0 {
+			igd.PonPortChannelMap.Remove(ponPortID)
+			ponRemoved = true
+		}
+		GetApplication().UpdateActiveChannelCountForPonPort(igd.Device, uniPort, ponPortID, false, deleted, igd)
+	} else {
+		logger.Warnw(ctx, "PON port doesn't exists in the igd", log.Fields{"PonPortID": ponPortID})
+	}
+	return ponRemoved
 }
 
 // printChannel to print channel info
 func printChannel(key interface{}, value interface{}) bool {
-        logger.Infow(ctx, "ChannelMap", log.Fields{"Channel": key.(string), "Igc": value.(*IgmpGroupChannel)})
-        return true
+	logger.Infow(ctx, "ChannelMap", log.Fields{"Channel": key.(string), "Igc": value.(*IgmpGroupChannel)})
+	return true
 }
 
 // printPortChannel to print port channel
 func printPortChannel(key interface{}, value interface{}) bool {
-        logger.Infow(ctx, "PortChannelMap", log.Fields{"Port": key.(string), "List": value.([]net.IP)})
-        return true
+	logger.Infow(ctx, "PortChannelMap", log.Fields{"Port": key.(string), "List": value.([]net.IP)})
+	return true
 }
 
-
 // AddReceiver add the receiver to the device and perform other actions such as adding the group
 // to the physical device, add members, add flows to point the MC packets to the
 // group. Also, send a IGMP report upstream if there is a change in the group
 func (igd *IgmpGroupDevice) AddReceiver(cntx context.Context, port string, groupAddr net.IP,
-        group *layers.IGMPv3GroupRecord, version uint8, cvlan uint16, pbit uint8, ponPortID uint32) {
+	group *layers.IGMPv3GroupRecord, version uint8, cvlan uint16, pbit uint8, ponPortID uint32) {
+	var igc *IgmpGroupChannel
+	logger.Debugw(ctx, "Processing receiver for device", log.Fields{"Channel": groupAddr, "Port": port, "Device": igd.Device})
 
-        var igc *IgmpGroupChannel
-        logger.Debugw(ctx, "Processing receiver for device", log.Fields{"Channel": groupAddr, "Port": port, "Device": igd.Device})
+	igcIntf, ok := igd.GroupChannels.Load(groupAddr.String())
+	if !ok {
+		igc = NewIgmpGroupChannel(igd, groupAddr, version)
+		igd.GroupChannels.Store(groupAddr.String(), igc)
+	} else {
+		igc = igcIntf.(*IgmpGroupChannel)
+	}
 
-        igcIntf, ok := igd.GroupChannels.Load(groupAddr.String())
-        if !ok {
-                igc = NewIgmpGroupChannel(igd, groupAddr, version)
-                igd.GroupChannels.Store(groupAddr.String(), igc)
-        } else {
-                igc = igcIntf.(*IgmpGroupChannel)
-        }
+	if !igd.GroupInstalled {
+		igd.AddNewReceiver(cntx, port, groupAddr, group, cvlan, pbit, ponPortID)
+		return
+	}
 
-        if !igd.GroupInstalled {
-                igd.AddNewReceiver(cntx, port, groupAddr, group, cvlan, pbit, ponPortID)
-                return
-        }
+	isNewReceiver := igc.AddReceiver(cntx, port, group, cvlan, pbit)
+	if isNewReceiver {
+		ipsList := []net.IP{}
+		ipsIntf, _ := igd.PortChannelMap.Load(port)
+		if ipsIntf != nil {
+			ipsList = ipsIntf.([]net.IP)
+		}
+		ipsList = append(ipsList, groupAddr)
+		igd.PortChannelMap.Store(port, ipsList)
+		logger.Debugw(ctx, "Port Channel Updated", log.Fields{"Port": port, "AddedChannelList": ipsList, "Addr": groupAddr})
 
-        isNewReceiver := igc.AddReceiver(cntx, port, group, cvlan, pbit)
-        if isNewReceiver {
-                ipsList := []net.IP{}
-                ipsIntf, _ := igd.PortChannelMap.Load(port)
-                if ipsIntf != nil {
-                        ipsList = ipsIntf.([]net.IP)
-                }
-                ipsList = append(ipsList, groupAddr)
-                igd.PortChannelMap.Store(port, ipsList)
-                logger.Debugw(ctx, "Port Channel Updated", log.Fields{"Port": port, "AddedChannelList": ipsList, "Addr": groupAddr})
-
-                isNewPonReceiver := igd.AddChannelToChannelsPerPon(port, groupAddr, ponPortID)
-                //Modify group only if this is the first time the port is subscribing for the group
-                if isNewPonReceiver {
-                        igd.ModMcGroup()
-                }
-        }
-        if err := igd.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
-        }
+		isNewPonReceiver := igd.AddChannelToChannelsPerPon(port, groupAddr, ponPortID)
+		//Modify group only if this is the first time the port is subscribing for the group
+		if isNewPonReceiver {
+			igd.ModMcGroup()
+		}
+	}
+	if err := igd.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
+	}
 }
 
 // AddNewReceiver to add new receiver
 func (igd *IgmpGroupDevice) AddNewReceiver(cntx context.Context, port string, groupAddr net.IP, group *layers.IGMPv3GroupRecord, cvlan uint16, pbit uint8, ponPortID uint32) {
+	logger.Debugw(ctx, "Adding New Device Receiver", log.Fields{"Channel": groupAddr, "Port": port, "Device": igd.Device})
+	igcIntf, _ := igd.GroupChannels.Load(groupAddr.String())
+	if igcIntf == nil {
+		logger.Warnw(ctx, "No Group Channel present for given channel", log.Fields{"Channel": groupAddr, "Port": port, "Device": igd.Device})
+		return
+	}
 
-        logger.Debugw(ctx, "Adding New Device Receiver", log.Fields{"Channel": groupAddr, "Port": port, "Device": igd.Device})
-        igcIntf, _ := igd.GroupChannels.Load(groupAddr.String())
-        if igcIntf == nil {
-                logger.Warnw(ctx, "No Group Channel present for given channel", log.Fields{"Channel": groupAddr, "Port": port, "Device": igd.Device})
-                return
-        }
+	igc := igcIntf.(*IgmpGroupChannel)
+	ipsList := []net.IP{}
+	ipsIntf, _ := igd.PortChannelMap.Load(port)
+	if ipsIntf != nil {
+		ipsList = ipsIntf.([]net.IP)
+	}
+	ipsList = append(ipsList, groupAddr)
+	igd.PortChannelMap.Store(port, ipsList)
+	igd.AddChannelToChannelsPerPon(port, groupAddr, ponPortID)
+	logger.Debugw(ctx, "Port Channel Updated", log.Fields{"Port": port, "NewChannelList": ipsList, "Addr": groupAddr})
 
-        igc := igcIntf.(*IgmpGroupChannel)
-        ipsList := []net.IP{}
-        ipsIntf, _ := igd.PortChannelMap.Load(port)
-        if ipsIntf != nil {
-                ipsList = ipsIntf.([]net.IP)
-        }
-        ipsList = append(ipsList, groupAddr)
-        igd.PortChannelMap.Store(port, ipsList)
-        igd.AddChannelToChannelsPerPon(port, groupAddr, ponPortID)
-        logger.Debugw(ctx, "Port Channel Updated", log.Fields{"Port": port, "NewChannelList": ipsList, "Addr": groupAddr})
-
-        igd.AddMcGroup()
-        igc.AddReceiver(cntx, port, group, cvlan, pbit)
-        if err := igd.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
-        }
+	igd.AddMcGroup()
+	igc.AddReceiver(cntx, port, group, cvlan, pbit)
+	if err := igd.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
+	}
 }
 
-
 // NumReceivers to get number of receivers
 func (igd *IgmpGroupDevice) NumReceivers() int {
-        var numReceivers int
-        len := func(key interface{}, value interface{}) bool {
-                numReceivers++
-                return true
-        }
-        igd.PortChannelMap.Range(len)
-        return numReceivers
+	var numReceivers int
+	len := func(key interface{}, value interface{}) bool {
+		numReceivers++
+		return true
+	}
+	igd.PortChannelMap.Range(len)
+	return numReceivers
 }
 
 // DelReceiver is called when Query expiry happened for a receiver. This removes the receiver from the
 // the group
 func (igd *IgmpGroupDevice) DelReceiver(cntx context.Context, groupAddr net.IP, port string, group *layers.IGMPv3GroupRecord, ponPortID uint32) {
+	logger.Debugw(ctx, "Deleting Receiver for Device", log.Fields{"port": port, "GroupIP": groupAddr.String()})
+	var igc *IgmpGroupChannel
+	var igcIntf interface{}
+	var ok bool
+	var srcList []net.IP
+	incl := false
+	mvp := GetApplication().GetMvlanProfileByTag(igd.Mvlan)
 
-        logger.Debugw(ctx, "Deleting Receiver for Device", log.Fields{"port": port, "GroupIP": groupAddr.String()})
-        var igc *IgmpGroupChannel
-        var igcIntf interface{}
-        var ok bool
-        var srcList []net.IP
-        incl := false
-        mvp := GetApplication().GetMvlanProfileByTag(igd.Mvlan)
+	if _, ok = mvp.Proxy[igd.GroupName]; ok {
+		incl = true
+	} else if group != nil {
+		srcList = group.SourceAddresses
+		incl = isIncl(group.Type)
+	}
 
-        if _, ok := mvp.Proxy[igd.GroupName]; ok {
-                incl = true
-        } else if group != nil {
-                srcList = group.SourceAddresses
-                incl = isIncl(group.Type)
-        }
+	if igcIntf, ok = igd.GroupChannels.Load(groupAddr.String()); !ok {
+		logger.Warnw(ctx, "Igmp Channel for group IP doesnt exist", log.Fields{"GroupAddr": groupAddr.String()})
+		return
+	}
+	igc = igcIntf.(*IgmpGroupChannel)
+	if ok := igc.DelReceiver(cntx, port, incl, srcList); !ok {
+		return
+	}
 
-        if igcIntf, ok = igd.GroupChannels.Load(groupAddr.String()); !ok {
-                logger.Warnw(ctx, "Igmp Channel for group IP doesnt exist", log.Fields{"GroupAddr": groupAddr.String()})
-                return
-        }
-        igc = igcIntf.(*IgmpGroupChannel)
-        if ok := igc.DelReceiver(cntx, port, incl, srcList); !ok {
-                return
-        }
+	if igc.NumReceivers() == 0 {
+		igd.DelIgmpGroupChannel(cntx, igc)
+	}
+	igd.DelPortFromChannel(port, groupAddr)
+	isGroupModified := igd.RemoveChannelFromChannelsPerPon(port, groupAddr, ponPortID)
 
-        if igc.NumReceivers() == 0 {
-                igd.DelIgmpGroupChannel(cntx, igc)
-        }
-        igd.DelPortFromChannel(port, groupAddr)
-        isGroupModified := igd.RemoveChannelFromChannelsPerPon(port, groupAddr, ponPortID)
-
-        //Remove port from receiver if port has no subscription to any of the group channels
-        if isGroupModified {
-                igd.ModMcGroup()
-        }
-        if err := igd.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
-        }
+	//Remove port from receiver if port has no subscription to any of the group channels
+	if isGroupModified {
+		igd.ModMcGroup()
+	}
+	if err := igd.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
+	}
 }
 
 // DelChannelReceiver is called when Query expiry happened for a receiver. This removes the receiver from the
 // the group
 func (igd *IgmpGroupDevice) DelChannelReceiver(cntx context.Context, groupAddr net.IP) map[string]*IgmpGroupPort {
+	portsRemoved := make(map[string]*IgmpGroupPort)
+	groupModified := false
+	// ifEmpty := true
+	igcIntf, _ := igd.GroupChannels.Load(groupAddr.String())
 
-        portsRemoved := make(map[string]*IgmpGroupPort)
-        groupModified := false
-        // ifEmpty := true
-        igcIntf, _ := igd.GroupChannels.Load(groupAddr.String())
+	if igcIntf == nil {
+		return portsRemoved
+	}
+	igc := igcIntf.(*IgmpGroupChannel)
 
-        if igcIntf == nil {
-                return portsRemoved
-        }
-        igc := igcIntf.(*IgmpGroupChannel)
+	for port, igp := range igc.NewReceivers {
+		_ = db.DelIgmpRcvr(cntx, igc.Mvlan, igc.GroupAddr, igc.Device, port) //TODO: Y not here
+		igd.DelPortFromChannel(port, igc.GroupAddr)
+		ponPortID := GetApplication().GetPonPortID(igd.Device, port)
+		groupModified = igd.RemoveChannelFromChannelsPerPon(port, igc.GroupAddr, ponPortID)
+		delete(igc.NewReceivers, port)
+		portsRemoved[port] = igp
+	}
+	for port, igp := range igc.CurReceivers {
+		_ = db.DelIgmpRcvr(cntx, igc.Mvlan, igc.GroupAddr, igc.Device, port)
+		igd.DelPortFromChannel(port, igc.GroupAddr)
+		ponPortID := GetApplication().GetPonPortID(igd.Device, port)
+		groupModified = igd.RemoveChannelFromChannelsPerPon(port, igc.GroupAddr, ponPortID)
+		delete(igc.CurReceivers, port)
+		portsRemoved[port] = igp
+	}
 
-        for port, igp := range igc.NewReceivers {
-                _ = db.DelIgmpRcvr(cntx, igc.Mvlan, igc.GroupAddr, igc.Device, port) //TODO: Y not here
-                igd.DelPortFromChannel(port, igc.GroupAddr)
-                ponPortID := GetApplication().GetPonPortID(igd.Device, port)
-                groupModified = igd.RemoveChannelFromChannelsPerPon(port, igc.GroupAddr, ponPortID)
-                delete(igc.NewReceivers, port)
-                portsRemoved[port] = igp
-        }
-        for port, igp := range igc.CurReceivers {
-                _ = db.DelIgmpRcvr(cntx, igc.Mvlan, igc.GroupAddr, igc.Device, port)
-                igd.DelPortFromChannel(port, igc.GroupAddr)
-                ponPortID := GetApplication().GetPonPortID(igd.Device, port)
-                groupModified = igd.RemoveChannelFromChannelsPerPon(port, igc.GroupAddr, ponPortID)
-                delete(igc.CurReceivers, port)
-                portsRemoved[port] = igp
-        }
+	igc.DelMcFlow(cntx)
+	igd.DelIgmpGroupChannel(cntx, igc)
+	igc.Exclude = 0
+	igc.SendLeaveToServer()
 
-        igc.DelMcFlow(cntx)
-        igd.DelIgmpGroupChannel(cntx, igc)
-        igc.Exclude = 0
-        igc.SendLeaveToServer()
-
-        if groupModified {
-                igd.ModMcGroup()
-        }
-        if err := igd.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
-        }
-        logger.Debugw(ctx, "Deleted the receiver Flow", log.Fields{"Num Receivers": igc.NumReceivers()})
-        return portsRemoved
+	if groupModified {
+		igd.ModMcGroup()
+	}
+	if err := igd.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device, "GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
+	}
+	logger.Debugw(ctx, "Deleted the receiver Flow", log.Fields{"Num Receivers": igc.NumReceivers()})
+	return portsRemoved
 }
 
 // DelIgmpGroupChannel to delete igmp group channel
 func (igd *IgmpGroupDevice) DelIgmpGroupChannel(cntx context.Context, igc *IgmpGroupChannel) {
-
-        if igc.NumReceivers() != 0 {
-                igc.DelAllReceivers(cntx)
-        }
-        _ = db.DelIgmpChannel(cntx, igc.Mvlan, igc.GroupName, igc.Device, igc.GroupAddr)
-        igd.GroupChannels.Delete(igc.GroupAddr.String())
-        logger.Infow(ctx, "Deleted the Channel from Device", log.Fields{"Channel": igc.GroupAddr.String()})
-        isLenZero := true
-        checkIfEmpty := func(key interface{}, value interface{}) bool {
-                isLenZero = false
-                return false
-        }
-        igd.GroupChannels.Range(checkIfEmpty)
-        if isLenZero {
-                logger.Infow(ctx, "No more active channels. Deleting MC Group", log.Fields{"Device": igd.Device, "Group": igd.GroupName})
-                igd.DelMcGroup(false)
-        }
+	if igc.NumReceivers() != 0 {
+		igc.DelAllReceivers(cntx)
+	}
+	_ = db.DelIgmpChannel(cntx, igc.Mvlan, igc.GroupName, igc.Device, igc.GroupAddr)
+	igd.GroupChannels.Delete(igc.GroupAddr.String())
+	logger.Infow(ctx, "Deleted the Channel from Device", log.Fields{"Channel": igc.GroupAddr.String()})
+	isLenZero := true
+	checkIfEmpty := func(key interface{}, value interface{}) bool {
+		isLenZero = false
+		return false
+	}
+	igd.GroupChannels.Range(checkIfEmpty)
+	if isLenZero {
+		logger.Infow(ctx, "No more active channels. Deleting MC Group", log.Fields{"Device": igd.Device, "Group": igd.GroupName})
+		igd.DelMcGroup(false)
+	}
 }
 
 // func (igd *IgmpGroupDevice) DelIgmpChannel(igc *IgmpGroupChannel) {
@@ -532,185 +515,182 @@
 
 // DelPortFromChannel to delete port from channel
 func (igd *IgmpGroupDevice) DelPortFromChannel(port string, groupAddr net.IP) bool {
-        ipsList := []net.IP{}
-        ipsListIntf, _ := igd.PortChannelMap.Load(port)
-        if ipsListIntf != nil {
-                ipsList = ipsListIntf.([]net.IP)
-        }
-        for i, addr := range ipsList {
-                if addr.Equal(groupAddr) {
-                        ipsList = append(ipsList[:i], ipsList[i+1:]...)
-                        //Remove port from receiver if port has no subscription to any of the group channels
-                        if len(ipsList) == 0 {
-                                igd.PortChannelMap.Delete(port)
-                        } else {
-                                //Update the map with modified ips list
-                                igd.PortChannelMap.Store(port, ipsList)
-                        }
-                        logger.Debugw(ctx, "Port Channel Updated", log.Fields{"Port": port, "DelChannelList": ipsList, "Addr": groupAddr.String()})
-                        return true
-                }
-        }
-        return false
+	ipsList := []net.IP{}
+	ipsListIntf, _ := igd.PortChannelMap.Load(port)
+	if ipsListIntf != nil {
+		ipsList = ipsListIntf.([]net.IP)
+	}
+	for i, addr := range ipsList {
+		if addr.Equal(groupAddr) {
+			ipsList = append(ipsList[:i], ipsList[i+1:]...)
+			//Remove port from receiver if port has no subscription to any of the group channels
+			if len(ipsList) == 0 {
+				igd.PortChannelMap.Delete(port)
+			} else {
+				//Update the map with modified ips list
+				igd.PortChannelMap.Store(port, ipsList)
+			}
+			logger.Debugw(ctx, "Port Channel Updated", log.Fields{"Port": port, "DelChannelList": ipsList, "Addr": groupAddr.String()})
+			return true
+		}
+	}
+	return false
 }
 
 // DelAllChannels deletes all receiver for the provided igmp device
 func (igd *IgmpGroupDevice) DelAllChannels(cntx context.Context) {
-        logger.Infow(ctx, "Deleting All Channel for Device", log.Fields{"Device": igd.Device, "Group": igd.GroupName})
-        delGroupChannels := func(key interface{}, value interface{}) bool {
-                igc := value.(*IgmpGroupChannel)
-                igd.DelIgmpGroupChannel(cntx, igc)
-                return true
-        }
-        igd.GroupChannels.Range(delGroupChannels)
+	logger.Infow(ctx, "Deleting All Channel for Device", log.Fields{"Device": igd.Device, "Group": igd.GroupName})
+	delGroupChannels := func(key interface{}, value interface{}) bool {
+		igc := value.(*IgmpGroupChannel)
+		igd.DelIgmpGroupChannel(cntx, igc)
+		return true
+	}
+	igd.GroupChannels.Range(delGroupChannels)
 }
 
 // ProcessQuery process query received from the upstream IGMP server
 func (igd *IgmpGroupDevice) ProcessQuery(cntx context.Context, groupAddr net.IP, ver uint8) {
-        logger.Debugw(ctx, "Received Query From Server", log.Fields{"Version": ver})
-        if ver != *igd.ServVersion {
-                igd.ServVersionExpiry = time.Now().Add(time.Duration(2*igd.proxyCfg.KeepAliveInterval) * time.Second)
-                *igd.ServVersion = ver
-                mvp := GetApplication().GetMvlanProfileByTag(igd.Mvlan)
-                if err := mvp.WriteToDb(cntx); err != nil {
-                        logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
-                }
-        }
-        if igc, ok := igd.GroupChannels.Load(groupAddr.String()); ok {
-                igc.(*IgmpGroupChannel).SendReport(true)
-                return
-        }
-        logger.Infow(ctx, "No Members for Channel. Dropping Igmp Query", log.Fields{"Group": igd.GroupName, "Channel": groupAddr.String()})
+	logger.Debugw(ctx, "Received Query From Server", log.Fields{"Version": ver})
+	if ver != *igd.ServVersion {
+		igd.ServVersionExpiry = time.Now().Add(time.Duration(2*igd.proxyCfg.KeepAliveInterval) * time.Second)
+		*igd.ServVersion = ver
+		mvp := GetApplication().GetMvlanProfileByTag(igd.Mvlan)
+		if err := mvp.WriteToDb(cntx); err != nil {
+			logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
+		}
+	}
+	if igc, ok := igd.GroupChannels.Load(groupAddr.String()); ok {
+		igc.(*IgmpGroupChannel).SendReport(true)
+		return
+	}
+	logger.Infow(ctx, "No Members for Channel. Dropping Igmp Query", log.Fields{"Group": igd.GroupName, "Channel": groupAddr.String()})
 }
 
 // AddMcGroup add the new group on the device when a receiver joins the group
 func (igd *IgmpGroupDevice) AddMcGroup() {
-        if !igd.GroupInstalled {
-                group := &of.Group{}
-                group.Command = of.GroupCommandAdd
-                group.GroupID = igd.GroupID
-                group.Device = igd.Device
-                group.SetVlan = igd.PonVlan
-                group.IsPonVlanPresent = igd.IsPonVlanPresent
+	if !igd.GroupInstalled {
+		group := &of.Group{}
+		group.Command = of.GroupCommandAdd
+		group.GroupID = igd.GroupID
+		group.Device = igd.Device
+		group.SetVlan = igd.PonVlan
+		group.IsPonVlanPresent = igd.IsPonVlanPresent
 
-                addbuckets := func(key interface{}, value interface{}) bool {
-                        port := key.(string)
-                        var portID uint32
-                        if d := GetApplication().GetDevice(group.Device); d != nil {
-                                GetApplication().portLock.Lock()
-                                p := d.GetPort(port)
-                                GetApplication().portLock.Unlock()
-                                portID = p.ID
-                        }
-                        //ponPortID := key.(uint32)
-                        if portID != 0xFF {
-                                group.Buckets = append(group.Buckets, portID)
-                        }
-                        return true
-                }
-                igd.PortChannelMap.Range(addbuckets)
+		addbuckets := func(key interface{}, value interface{}) bool {
+			port := key.(string)
+			var portID uint32
+			if d := GetApplication().GetDevice(group.Device); d != nil {
+				GetApplication().portLock.Lock()
+				p := d.GetPort(port)
+				GetApplication().portLock.Unlock()
+				portID = p.ID
+			}
+			//ponPortID := key.(uint32)
+			if portID != 0xFF {
+				group.Buckets = append(group.Buckets, portID)
+			}
+			return true
+		}
+		igd.PortChannelMap.Range(addbuckets)
 
-                port, _ := GetApplication().GetNniPort(igd.Device)
-                _ = cntlr.GetController().GroupUpdate(port, igd.Device, group)
-                igd.GroupInstalled = true
-        }
+		port, _ := GetApplication().GetNniPort(igd.Device)
+		_ = cntlr.GetController().GroupUpdate(port, igd.Device, group)
+		igd.GroupInstalled = true
+	}
 }
 
 // ModMcGroup updates the group on the device when either a receiver leaves
 // or joins the group
 func (igd *IgmpGroupDevice) ModMcGroup() {
-        if igd.GroupInstalled {
-                group := &of.Group{}
-                group.Command = of.GroupCommandMod
-                group.GroupID = igd.GroupID
-                group.Device = igd.Device
-                group.SetVlan = igd.PonVlan
-                group.IsPonVlanPresent = igd.IsPonVlanPresent
+	if igd.GroupInstalled {
+		group := &of.Group{}
+		group.Command = of.GroupCommandMod
+		group.GroupID = igd.GroupID
+		group.Device = igd.Device
+		group.SetVlan = igd.PonVlan
+		group.IsPonVlanPresent = igd.IsPonVlanPresent
 
-                addbuckets := func(key interface{}, value interface{}) bool {
-                       port := key.(string)
-                       var portID uint32
-                       if d := GetApplication().GetDevice(group.Device); d != nil {
-                               GetApplication().portLock.Lock()
-                               p := d.GetPort(port)
-                               GetApplication().portLock.Unlock()
-                               portID = p.ID
-                       }
-                       //ponPortID := key.(uint32)
-                       if portID != 0xFF {
-                               group.Buckets = append(group.Buckets, portID)
-                        }
-                        return true
-                }
-                igd.PortChannelMap.Range(addbuckets)
+		addbuckets := func(key interface{}, value interface{}) bool {
+			port := key.(string)
+			var portID uint32
+			if d := GetApplication().GetDevice(group.Device); d != nil {
+				GetApplication().portLock.Lock()
+				p := d.GetPort(port)
+				GetApplication().portLock.Unlock()
+				portID = p.ID
+			}
+			//ponPortID := key.(uint32)
+			if portID != 0xFF {
+				group.Buckets = append(group.Buckets, portID)
+			}
+			return true
+		}
+		igd.PortChannelMap.Range(addbuckets)
 
-                port, _ := GetApplication().GetNniPort(igd.Device)
-                _ = cntlr.GetController().GroupUpdate(port, igd.Device, group)
-        } else {
-                logger.Warnw(ctx, "Update Group Failed. Group not yet created", log.Fields{"Igd": igd.Device})
-        }
+		port, _ := GetApplication().GetNniPort(igd.Device)
+		_ = cntlr.GetController().GroupUpdate(port, igd.Device, group)
+	} else {
+		logger.Warnw(ctx, "Update Group Failed. Group not yet created", log.Fields{"Igd": igd.Device})
+	}
 }
 
 // DelMcGroup : The group is deleted when the last receiver leaves the group
 func (igd *IgmpGroupDevice) DelMcGroup(forceDelete bool) {
+	logger.Infow(ctx, "Delete Mc Group Request", log.Fields{"Device": igd.Device, "GroupID": igd.GroupID, "ForceFlag": forceDelete, "GroupInstalled": igd.GroupInstalled})
+	/*
+	   if !forceDelete && !checkIfForceGroupRemove(igd.Device) {
+	           if success := AddToPendingPool(igd.Device, igd.getKey()); success {
+	                   return
+	           }
+	   }*/
+	if igd.GroupInstalled {
+		logger.Debugw(ctx, "Deleting Group", log.Fields{"Device": igd.Device, "Id": igd.GroupID})
+		group := &of.Group{}
+		group.Command = of.GroupCommandDel
+		group.GroupID = igd.GroupID
+		group.Device = igd.Device
+		group.ForceAction = true
 
-        logger.Infow(ctx, "Delete Mc Group Request", log.Fields{"Device": igd.Device, "GroupID": igd.GroupID, "ForceFlag": forceDelete, "GroupInstalled": igd.GroupInstalled})
-        /*
-        if !forceDelete && !checkIfForceGroupRemove(igd.Device) {
-                if success := AddToPendingPool(igd.Device, igd.getKey()); success {
-                        return
-                }
-        }*/
-        if igd.GroupInstalled {
-                logger.Debugw(ctx, "Deleting Group", log.Fields{"Device": igd.Device, "Id": igd.GroupID})
-                group := &of.Group{}
-                group.Command = of.GroupCommandDel
-                group.GroupID = igd.GroupID
-                group.Device = igd.Device
-                group.ForceAction = true
-
-                port, _ := GetApplication().GetNniPort(igd.Device)
-                _ = cntlr.GetController().GroupUpdate(port, igd.Device, group)
-                igd.GroupInstalled = false
-        }
+		port, _ := GetApplication().GetNniPort(igd.Device)
+		_ = cntlr.GetController().GroupUpdate(port, igd.Device, group)
+		igd.GroupInstalled = false
+	}
 }
 
 // QueryExpiry processes query expiry. Upon expiry, take stock of the situation
 // add either retain/release the group based on number of receivers left
 func (igd *IgmpGroupDevice) QueryExpiry(cntx context.Context) {
-        logger.Debugw(ctx, "Query Expiry", log.Fields{"Device": igd.Device})
+	logger.Debugw(ctx, "Query Expiry", log.Fields{"Device": igd.Device})
 
+	// Delete the IGMP flow added for this port if port state is down or query count exceeded
+	handleQueryExp := func(key interface{}, value interface{}) bool {
+		igc := value.(*IgmpGroupChannel)
+		for portKey, port := range igc.CurReceivers {
+			if portKey == StaticPort {
+				continue
+			}
 
-        // Delete the IGMP flow added for this port if port state is down or query count exceeded
-        handleQueryExp := func(key interface{}, value interface{}) bool {
-                igc := value.(*IgmpGroupChannel)
-                for portKey, port := range igc.CurReceivers {
+			logger.Warnw(ctx, "Expired Receiver Port", log.Fields{"PortKey": portKey, "IGP": port, "GroupAddr": igc.GroupAddr,
+				"Count": port.QueryTimeoutCount})
+			state, err := cntlr.GetController().GetPortState(igc.Device, portKey)
+			logger.Debugw(ctx, "Expired Member Port State", log.Fields{"state": state})
+			ponPortID := GetApplication().GetPonPortID(igd.Device, portKey)
+			if err == nil && state == cntlr.PortStateDown {
+				igd.DelReceiver(cntx, igc.GroupAddr, portKey, nil, ponPortID)
+			}
 
-                        if portKey == StaticPort {
-                                continue
-                        }
-
-                        logger.Warnw(ctx, "Expired Receiver Port", log.Fields{"PortKey": portKey, "IGP": port, "GroupAddr": igc.GroupAddr,
-                                "Count": port.QueryTimeoutCount})
-                        state, err := cntlr.GetController().GetPortState(igc.Device, portKey)
-                        logger.Debugw(ctx, "Expired Member Port State", log.Fields{"state": state})
-                        ponPortID := GetApplication().GetPonPortID(igd.Device, portKey)
-                        if err == nil && state == cntlr.PortStateDown {
-                                igd.DelReceiver(cntx, igc.GroupAddr, portKey, nil, ponPortID)
-                        }
-
-                        port.QueryTimeoutCount++
-                        logger.Debugw(ctx, "Expired Port TimeoutCount", log.Fields{"count": port.QueryTimeoutCount})
-                        if port.QueryTimeoutCount >= (*igc.proxyCfg).KeepAliveCount {
-                                logger.Errorw(ctx, "Expiry Timeout count exceeded. Trigger delete receiver", log.Fields{"PortKey": portKey,
-                                        "GroupAddr": igc.GroupAddr, "Count": port.QueryTimeoutCount})
-                                igd.DelReceiver(cntx, igc.GroupAddr, portKey, nil, ponPortID)
-                                SendQueryExpiredEventGroupSpecific(portKey, igd, igc)
-                        } else {
-                                _ = port.WriteToDb(cntx, igc.Mvlan, igc.GroupAddr, igc.Device)
-                        }
-                }
-                return true
-        }
-        igd.GroupChannels.Range(handleQueryExp)
+			port.QueryTimeoutCount++
+			logger.Debugw(ctx, "Expired Port TimeoutCount", log.Fields{"count": port.QueryTimeoutCount})
+			if port.QueryTimeoutCount >= (*igc.proxyCfg).KeepAliveCount {
+				logger.Errorw(ctx, "Expiry Timeout count exceeded. Trigger delete receiver", log.Fields{"PortKey": portKey,
+					"GroupAddr": igc.GroupAddr, "Count": port.QueryTimeoutCount})
+				igd.DelReceiver(cntx, igc.GroupAddr, portKey, nil, ponPortID)
+				SendQueryExpiredEventGroupSpecific(portKey, igd, igc)
+			} else {
+				_ = port.WriteToDb(cntx, igc.Mvlan, igc.GroupAddr, igc.Device)
+			}
+		}
+		return true
+	}
+	igd.GroupChannels.Range(handleQueryExp)
 }
diff --git a/internal/pkg/application/igmpponportchannel.go b/internal/pkg/application/igmpponportchannel.go
index 6c31ad4..4f858e8 100644
--- a/internal/pkg/application/igmpponportchannel.go
+++ b/internal/pkg/application/igmpponportchannel.go
@@ -11,7 +11,7 @@
 * 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 application
 
@@ -23,76 +23,74 @@
 // UniPortList : UNI Port list per channle has stores the UNI port list for this
 // channel.
 type UniPortList struct {
-        UNIList *util.ConcurrentMap // [UNIPort] UNIPort
+	UNIList *util.ConcurrentMap // [UNIPort] UNIPort
 }
 
 // NewUniPortsList is Constructor for UniPortList structure
 func NewUniPortsList() *UniPortList {
-        var uniPortsList UniPortList
+	var uniPortsList UniPortList
 
-        uniPortsList.UNIList = util.NewConcurrentMap()
-        return &uniPortsList
+	uniPortsList.UNIList = util.NewConcurrentMap()
+	return &uniPortsList
 }
 
 // GetUniPortCount returns the number of UNI ports subscribed to
 // current channel.
 func (uniPortsList *UniPortList) GetUniPortCount() uint64 {
-        return uniPortsList.UNIList.Length()
+	return uniPortsList.UNIList.Length()
 }
 
 // PonPortChannels : PON port channel map keeps the active channel list and its
 // count for this group.
 type PonPortChannels struct {
-        ChannelList *util.ConcurrentMap // [channelIP]*UniPortList
+	ChannelList *util.ConcurrentMap // [channelIP]*UniPortList
 }
 
 // NewPonPortChannels is constructor for PonPortChannel.
 func NewPonPortChannels() *PonPortChannels {
-        var ponPortChannel PonPortChannels
+	var ponPortChannel PonPortChannels
 
-        ponPortChannel.ChannelList = util.NewConcurrentMap()
-        return &ponPortChannel
+	ponPortChannel.ChannelList = util.NewConcurrentMap()
+	return &ponPortChannel
 }
 
 // GetActiveChannelCount returns the number of active channel count
 // for this pon port in the current group.
 func (ponPortChannels *PonPortChannels) GetActiveChannelCount() uint32 {
-        return uint32(ponPortChannels.ChannelList.Length())
+	return uint32(ponPortChannels.ChannelList.Length())
 }
 
 // AddChannelToMap Adds new channel to the pon port map
 func (ponPortChannels *PonPortChannels) AddChannelToMap(uniPort, channel string) bool {
-
-        isNewChannel := bool(false)
-        uniList, ok := ponPortChannels.ChannelList.Get(channel)
-        if !ok {
-                // Channel doesn't exists. Adding new channel.
-                uniList = NewUniPortsList()
-                isNewChannel = true
-        }
-        uniList.(*UniPortList).UNIList.Set(uniPort, uniPort)
-        ponPortChannels.ChannelList.Set(channel, uniList)
-        return isNewChannel
+	isNewChannel := bool(false)
+	uniList, ok := ponPortChannels.ChannelList.Get(channel)
+	if !ok {
+		// Channel doesn't exists. Adding new channel.
+		uniList = NewUniPortsList()
+		isNewChannel = true
+	}
+	uniList.(*UniPortList).UNIList.Set(uniPort, uniPort)
+	ponPortChannels.ChannelList.Set(channel, uniList)
+	return isNewChannel
 }
 
 // RemoveChannelFromMap Removed channel from the pon port map
 func (ponPortChannels *PonPortChannels) RemoveChannelFromMap(uniPort, channel string) bool {
-
-        isDeleted := bool(false)
-        uniList, ok := ponPortChannels.ChannelList.Get(channel)
-        if ok {
-                uniList.(*UniPortList).UNIList.Remove(uniPort)
-                if uniList.(*UniPortList).UNIList.Length() == 0 {
-                        // Last port from the channel is removed.
-                        // Removing channel from PON port map.
-                        ponPortChannels.ChannelList.Remove(channel)
-                        isDeleted = true
-                } else {
-                        ponPortChannels.ChannelList.Set(channel, uniList)
-                }
-        } else {
-                logger.Warnw(ctx, "Channel doesn't exists in the active channels list", log.Fields{"Channel": channel})
-                return isDeleted
-        }
-        return isDeleted
+	isDeleted := bool(false)
+	uniList, ok := ponPortChannels.ChannelList.Get(channel)
+	if ok {
+		uniList.(*UniPortList).UNIList.Remove(uniPort)
+		if uniList.(*UniPortList).UNIList.Length() == 0 {
+			// Last port from the channel is removed.
+			// Removing channel from PON port map.
+			ponPortChannels.ChannelList.Remove(channel)
+			isDeleted = true
+		} else {
+			ponPortChannels.ChannelList.Set(channel, uniList)
+		}
+	} else {
+		logger.Warnw(ctx, "Channel doesn't exists in the active channels list", log.Fields{"Channel": channel})
+		return isDeleted
+	}
+	return isDeleted
 }
diff --git a/internal/pkg/application/igmpport.go b/internal/pkg/application/igmpport.go
index b22b901..171fca0 100644
--- a/internal/pkg/application/igmpport.go
+++ b/internal/pkg/application/igmpport.go
@@ -11,7 +11,7 @@
 * 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 application
 
@@ -21,7 +21,7 @@
 	"net"
 
 	"voltha-go-controller/internal/pkg/of"
-        "voltha-go-controller/log"
+	"voltha-go-controller/log"
 )
 
 // IgmpGroupPort : IGMP port implements a port which is associated with an IGMP
@@ -32,92 +32,92 @@
 // lists. If we receive a include list we should purge the other
 // list which is TODO
 type IgmpGroupPort struct {
-        Port              string
-        CVlan             uint16
-        Pbit              uint8
-        Version           uint8
-        Exclude           bool
-        ExcludeList       []net.IP
-        IncludeList       []net.IP
-        QueryTimeoutCount uint32
-        PonPortID         uint32
+	Port              string
+	ExcludeList       []net.IP
+	IncludeList       []net.IP
+	QueryTimeoutCount uint32
+	PonPortID         uint32
+	CVlan             uint16
+	Pbit              uint8
+	Version           uint8
+	Exclude           bool
 }
 
 // NewIgmpGroupPort is constructor for a port
 func NewIgmpGroupPort(port string, cvlan uint16, pbit uint8, version uint8, incl bool, ponPortID uint32) *IgmpGroupPort {
-        var igp IgmpGroupPort
-        igp.Port = port
-        igp.CVlan = cvlan
-        igp.Pbit = pbit
-        igp.Version = version
-        igp.Exclude = !incl
-        igp.QueryTimeoutCount = 0
-        igp.PonPortID = ponPortID
-        return &igp
+	var igp IgmpGroupPort
+	igp.Port = port
+	igp.CVlan = cvlan
+	igp.Pbit = pbit
+	igp.Version = version
+	igp.Exclude = !incl
+	igp.QueryTimeoutCount = 0
+	igp.PonPortID = ponPortID
+	return &igp
 }
 
 // InclSourceIsIn checks if a source is in include list
 func (igp *IgmpGroupPort) InclSourceIsIn(src net.IP) bool {
-        return IsIPPresent(src, igp.IncludeList)
+	return IsIPPresent(src, igp.IncludeList)
 }
 
 // ExclSourceIsIn checks if a source is in exclude list
 func (igp *IgmpGroupPort) ExclSourceIsIn(src net.IP) bool {
-        return IsIPPresent(src, igp.ExcludeList)
+	return IsIPPresent(src, igp.ExcludeList)
 }
 
 // AddInclSource adds a source is in include list
 func (igp *IgmpGroupPort) AddInclSource(src net.IP) {
-        logger.Debugw(ctx, "Adding Include Source", log.Fields{"Port": igp.Port, "Src": src})
-        igp.IncludeList = append(igp.IncludeList, src)
+	logger.Debugw(ctx, "Adding Include Source", log.Fields{"Port": igp.Port, "Src": src})
+	igp.IncludeList = append(igp.IncludeList, src)
 }
 
 // AddExclSource adds a source is in exclude list
 func (igp *IgmpGroupPort) AddExclSource(src net.IP) {
-        logger.Debugw(ctx, "Adding Exclude Source", log.Fields{"Port": igp.Port, "Src": src})
-        igp.ExcludeList = append(igp.ExcludeList, src)
+	logger.Debugw(ctx, "Adding Exclude Source", log.Fields{"Port": igp.Port, "Src": src})
+	igp.ExcludeList = append(igp.ExcludeList, src)
 }
 
 // DelInclSource deletes a source is in include list
 func (igp *IgmpGroupPort) DelInclSource(src net.IP) {
-        logger.Debugw(ctx, "Deleting Include Source", log.Fields{"Port": igp.Port, "Src": src})
-        for i, addr := range igp.IncludeList {
-                if addr.Equal(src) {
-                        igp.IncludeList = append(igp.IncludeList[:i], igp.IncludeList[i+1:]...)
-                        return
-                }
-        }
+	logger.Debugw(ctx, "Deleting Include Source", log.Fields{"Port": igp.Port, "Src": src})
+	for i, addr := range igp.IncludeList {
+		if addr.Equal(src) {
+			igp.IncludeList = append(igp.IncludeList[:i], igp.IncludeList[i+1:]...)
+			return
+		}
+	}
 }
 
 // DelExclSource deletes a source is in exclude list
 func (igp *IgmpGroupPort) DelExclSource(src net.IP) {
-        logger.Debugw(ctx, "Deleting Exclude Source", log.Fields{"Port": igp.Port, "Src": src})
-        for i, addr := range igp.ExcludeList {
-                if addr.Equal(src) {
-                        igp.ExcludeList = append(igp.ExcludeList[:i], igp.ExcludeList[i+1:]...)
-                        return
-                }
-        }
+	logger.Debugw(ctx, "Deleting Exclude Source", log.Fields{"Port": igp.Port, "Src": src})
+	for i, addr := range igp.ExcludeList {
+		if addr.Equal(src) {
+			igp.ExcludeList = append(igp.ExcludeList[:i], igp.ExcludeList[i+1:]...)
+			return
+		}
+	}
 }
 
 // WriteToDb is utility to write IGMP Group Port Info to database
 func (igp *IgmpGroupPort) WriteToDb(cntx context.Context, mvlan of.VlanType, gip net.IP, device string) error {
-        b, err := json.Marshal(igp)
-        if err != nil {
-                return err
-        }
-        if err1 := db.PutIgmpRcvr(cntx, mvlan, gip, device, igp.Port, string(b)); err1 != nil {
-                return err1
-        }
-        return nil
+	b, err := json.Marshal(igp)
+	if err != nil {
+		return err
+	}
+	if err1 := db.PutIgmpRcvr(cntx, mvlan, gip, device, igp.Port, string(b)); err1 != nil {
+		return err1
+	}
+	return nil
 }
 
 // NewIgmpGroupPortFromBytes create the IGMP group port from a byte slice
 func NewIgmpGroupPortFromBytes(b []byte) (*IgmpGroupPort, error) {
-        var igp IgmpGroupPort
-        if err := json.Unmarshal(b, &igp); err != nil {
-                logger.Warnw(ctx, "Decode of port failed", log.Fields{"str": string(b)})
-                return nil, err
-        }
-        return &igp, nil
+	var igp IgmpGroupPort
+	if err := json.Unmarshal(b, &igp); err != nil {
+		logger.Warnw(ctx, "Decode of port failed", log.Fields{"str": string(b)})
+		return nil, err
+	}
+	return &igp, nil
 }
diff --git a/internal/pkg/application/igmpprofiles.go b/internal/pkg/application/igmpprofiles.go
index b855eb8..a1d999c 100644
--- a/internal/pkg/application/igmpprofiles.go
+++ b/internal/pkg/application/igmpprofiles.go
@@ -11,7 +11,7 @@
 * 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 application
 
@@ -24,10 +24,10 @@
 	"strings"
 	"sync"
 
-	cntlr "voltha-go-controller/internal/pkg/controller"
-	"voltha-go-controller/internal/pkg/types"
 	"voltha-go-controller/database"
+	cntlr "voltha-go-controller/internal/pkg/controller"
 	"voltha-go-controller/internal/pkg/of"
+	common "voltha-go-controller/internal/pkg/types"
 	"voltha-go-controller/internal/pkg/util"
 	"voltha-go-controller/log"
 )
@@ -45,30 +45,30 @@
 
 // MCGroupProxy identifies source specific multicast(SSM) config.
 type MCGroupProxy struct {
-        // Mode represents source list include/exclude
-        Mode common.MulticastSrcListMode
-        // SourceList represents list of multicast server IP addresses.
-        SourceList []net.IP
+	// Mode represents source list include/exclude
+	Mode common.MulticastSrcListMode
+	// SourceList represents list of multicast server IP addresses.
+	SourceList []net.IP
 }
 
 // MvlanGroup identifies MC group info
 type MvlanGroup struct {
-        Name     string
-        Wildcard bool
-        McIPs    []string
-        IsStatic bool
+	Name     string
+	McIPs    []string
+	Wildcard bool
+	IsStatic bool
 }
 
 // OperInProgress type
 type OperInProgress uint8
 
 const (
-        // UpdateInProgress constant
-        UpdateInProgress OperInProgress = 2
-        // NoOp constant
-        NoOp OperInProgress = 1
-        // Nil constant
-        Nil OperInProgress = 0
+	// UpdateInProgress constant
+	UpdateInProgress OperInProgress = 2
+	// NoOp constant
+	NoOp OperInProgress = 1
+	// Nil constant
+	Nil OperInProgress = 0
 )
 
 // MvlanProfile : A set of groups of MC IPs for a MVLAN profile. It is assumed that
@@ -76,1155 +76,1134 @@
 // MVLAN profiles. The first match is used up on search to lcoate the
 // MVLAN profile for an MC IP
 type MvlanProfile struct {
-        Name                string
-        Mvlan               of.VlanType
-        PonVlan             of.VlanType
-        Groups              map[string]*MvlanGroup
-        Proxy               map[string]*MCGroupProxy
-        Version             string
-        IsPonVlanPresent    bool
-        IsChannelBasedGroup bool
-        DevicesList         map[string]OperInProgress //device serial number //here
-        oldGroups           map[string]*MvlanGroup
-        oldProxy            map[string]*MCGroupProxy
-        MaxActiveChannels   uint32
-        PendingDeleteFlow   map[string]map[string]bool
-        DeleteInProgress    bool
-        IgmpServVersion     map[string]*uint8
-        mvpLock             sync.RWMutex
-        mvpFlowLock         sync.RWMutex
+	Groups              map[string]*MvlanGroup
+	Proxy               map[string]*MCGroupProxy
+	oldGroups           map[string]*MvlanGroup
+	oldProxy            map[string]*MCGroupProxy
+	IgmpServVersion     map[string]*uint8
+	PendingDeleteFlow   map[string]map[string]bool
+	DevicesList         map[string]OperInProgress //device serial number //here
+	Version             string
+	Name                string
+	mvpLock             sync.RWMutex
+	mvpFlowLock         sync.RWMutex
+	MaxActiveChannels   uint32
+	Mvlan               of.VlanType
+	PonVlan             of.VlanType
+	IsPonVlanPresent    bool
+	IsChannelBasedGroup bool
+	DeleteInProgress    bool
 }
 
 // NewMvlanProfile is constructor for MVLAN profile.
 func NewMvlanProfile(name string, mvlan of.VlanType, ponVlan of.VlanType, isChannelBasedGroup bool, OLTSerialNums []string, actChannelPerPon uint32) *MvlanProfile {
-        var mvp MvlanProfile
-        mvp.Name = name
-        mvp.Mvlan = mvlan
-        mvp.PonVlan = ponVlan
-        mvp.mvpLock = sync.RWMutex{}
-        mvp.Groups = make(map[string]*MvlanGroup)
-        mvp.Proxy = make(map[string]*MCGroupProxy)
-        mvp.DevicesList = make(map[string]OperInProgress)
-        mvp.PendingDeleteFlow = make(map[string]map[string]bool)
-        mvp.IsChannelBasedGroup = isChannelBasedGroup
-        mvp.MaxActiveChannels = actChannelPerPon
-        mvp.DeleteInProgress = false
-        mvp.IgmpServVersion = make(map[string]*uint8)
+	var mvp MvlanProfile
+	mvp.Name = name
+	mvp.Mvlan = mvlan
+	mvp.PonVlan = ponVlan
+	mvp.mvpLock = sync.RWMutex{}
+	mvp.Groups = make(map[string]*MvlanGroup)
+	mvp.Proxy = make(map[string]*MCGroupProxy)
+	mvp.DevicesList = make(map[string]OperInProgress)
+	mvp.PendingDeleteFlow = make(map[string]map[string]bool)
+	mvp.IsChannelBasedGroup = isChannelBasedGroup
+	mvp.MaxActiveChannels = actChannelPerPon
+	mvp.DeleteInProgress = false
+	mvp.IgmpServVersion = make(map[string]*uint8)
 
-        if (ponVlan != of.VlanNone) && (ponVlan != 0) {
-                mvp.IsPonVlanPresent = true
-        }
-        return &mvp
+	if (ponVlan != of.VlanNone) && (ponVlan != 0) {
+		mvp.IsPonVlanPresent = true
+	}
+	return &mvp
 }
 
 // AddMvlanProxy for addition of groups to an MVLAN profile
 func (mvp *MvlanProfile) AddMvlanProxy(name string, proxyInfo common.MulticastGroupProxy) {
-        proxy := &MCGroupProxy{}
-        proxy.Mode = proxyInfo.Mode
-        proxy.SourceList = util.GetExpIPList(proxyInfo.SourceList)
+	proxy := &MCGroupProxy{}
+	proxy.Mode = proxyInfo.Mode
+	proxy.SourceList = util.GetExpIPList(proxyInfo.SourceList)
 
-        if _, ok := mvp.Proxy[name]; !ok {
-                logger.Debugw(ctx, "Added MVLAN Proxy", log.Fields{"Name": name, "Proxy": proxy})
-        } else {
-                logger.Debugw(ctx, "Updated MVLAN Proxy", log.Fields{"Name": name, "Proxy": proxy})
-        }
-        if proxyInfo.IsStatic == common.IsStaticYes {
-                mvp.Groups[name].IsStatic = true
-        }
-        mvp.Proxy[name] = proxy
+	if _, ok := mvp.Proxy[name]; !ok {
+		logger.Debugw(ctx, "Added MVLAN Proxy", log.Fields{"Name": name, "Proxy": proxy})
+	} else {
+		logger.Debugw(ctx, "Updated MVLAN Proxy", log.Fields{"Name": name, "Proxy": proxy})
+	}
+	if proxyInfo.IsStatic == common.IsStaticYes {
+		mvp.Groups[name].IsStatic = true
+	}
+	mvp.Proxy[name] = proxy
 }
 
 // AddMvlanGroup for addition of groups to an MVLAN profile
 func (mvp *MvlanProfile) AddMvlanGroup(name string, ips []string) {
-        mvg := &MvlanGroup{}
-        mvg.Name = name
-        mvg.Wildcard = len(ips) == 0
-        mvg.McIPs = ips
-        mvg.IsStatic = false
-        if _, ok := mvp.Groups[name]; !ok {
-                logger.Debugw(ctx, "Added MVLAN Group", log.Fields{"VLAN": mvp.Mvlan, "Name": name, "mvg": mvg, "IPs": mvg.McIPs})
-        } else {
-                logger.Debugw(ctx, "Updated MVLAN Group", log.Fields{"VLAN": mvp.Mvlan, "Name": name})
-        }
-        mvp.Groups[name] = mvg
+	mvg := &MvlanGroup{}
+	mvg.Name = name
+	mvg.Wildcard = len(ips) == 0
+	mvg.McIPs = ips
+	mvg.IsStatic = false
+	if _, ok := mvp.Groups[name]; !ok {
+		logger.Debugw(ctx, "Added MVLAN Group", log.Fields{"VLAN": mvp.Mvlan, "Name": name, "mvg": mvg, "IPs": mvg.McIPs})
+	} else {
+		logger.Debugw(ctx, "Updated MVLAN Group", log.Fields{"VLAN": mvp.Mvlan, "Name": name})
+	}
+	mvp.Groups[name] = mvg
 }
 
 // GetUsMatchVlan provides mvlan for US Match parameter
 func (mvp *MvlanProfile) GetUsMatchVlan() of.VlanType {
-        if mvp.IsPonVlanPresent {
-                return mvp.PonVlan
-        }
-        return mvp.Mvlan
+	if mvp.IsPonVlanPresent {
+		return mvp.PonVlan
+	}
+	return mvp.Mvlan
 }
 
 // WriteToDb is utility to write Mvlan Profile Info to database
 func (mvp *MvlanProfile) WriteToDb(cntx context.Context) error {
+	if mvp.DeleteInProgress {
+		logger.Warnw(ctx, "Skipping Redis Update for MvlanProfile, MvlanProfile delete in progress", log.Fields{"Mvlan": mvp.Mvlan})
+		return nil
+	}
 
-        if mvp.DeleteInProgress {
-                logger.Warnw(ctx, "Skipping Redis Update for MvlanProfile, MvlanProfile delete in progress", log.Fields{"Mvlan": mvp.Mvlan})
-                return nil
-        }
-
-        mvp.Version = database.PresentVersionMap[database.MvlanPath]
-        b, err := json.Marshal(mvp)
-        if err != nil {
-                return err
-        }
-        if err1 := db.PutMvlan(cntx, uint16(mvp.Mvlan), string(b)); err1 != nil {
-                return err1
-        }
-        return nil
+	mvp.Version = database.PresentVersionMap[database.MvlanPath]
+	b, err := json.Marshal(mvp)
+	if err != nil {
+		return err
+	}
+	if err1 := db.PutMvlan(cntx, uint16(mvp.Mvlan), string(b)); err1 != nil {
+		return err1
+	}
+	return nil
 }
 
-//isChannelStatic - Returns true if the given channel is part of static group in the Mvlan Profile
+// isChannelStatic - Returns true if the given channel is part of static group in the Mvlan Profile
 func (mvp *MvlanProfile) isChannelStatic(channel net.IP) bool {
-        for _, mvg := range mvp.Groups {
-                if mvg.IsStatic {
-                        if isChannelStatic := doesIPMatch(channel, mvg.McIPs); isChannelStatic {
-                                return true
-                        }
-                }
-        }
-        return false
+	for _, mvg := range mvp.Groups {
+		if mvg.IsStatic {
+			if isChannelStatic := doesIPMatch(channel, mvg.McIPs); isChannelStatic {
+				return true
+			}
+		}
+	}
+	return false
 }
 
-//containsStaticChannels - Returns if any static channels is part of the Mvlan Profile
+// containsStaticChannels - Returns if any static channels is part of the Mvlan Profile
 func (mvp *MvlanProfile) containsStaticChannels() bool {
-        for _, mvg := range mvp.Groups {
-                if mvg.IsStatic && len(mvg.McIPs) != 0 {
-                        return true
-                }
-        }
-        return false
+	for _, mvg := range mvp.Groups {
+		if mvg.IsStatic && len(mvg.McIPs) != 0 {
+			return true
+		}
+	}
+	return false
 }
 
-//getAllStaticChannels - Returns all static channels in the Mvlan Profile
+// getAllStaticChannels - Returns all static channels in the Mvlan Profile
 func (mvp *MvlanProfile) getAllStaticChannels() ([]net.IP, bool) {
-        channelList := []net.IP{}
-        containsStatic := false
-        for _, mvg := range mvp.Groups {
-                if mvg.IsStatic {
-                        staticChannels, _ := mvg.getAllChannels()
-                        channelList = append(channelList, staticChannels...)
-                }
-        }
-        if len(channelList) > 0 {
-                containsStatic = true
-        }
-        return channelList, containsStatic
+	channelList := []net.IP{}
+	containsStatic := false
+	for _, mvg := range mvp.Groups {
+		if mvg.IsStatic {
+			staticChannels, _ := mvg.getAllChannels()
+			channelList = append(channelList, staticChannels...)
+		}
+	}
+	if len(channelList) > 0 {
+		containsStatic = true
+	}
+	return channelList, containsStatic
 }
 
-//getAllOldGroupStaticChannels - Returns all static channels in the Mvlan Profile
+// getAllOldGroupStaticChannels - Returns all static channels in the Mvlan Profile
 func (mvp *MvlanProfile) getAllOldGroupStaticChannels() ([]net.IP, bool) {
-        channelList := []net.IP{}
-        containsStatic := false
-        for _, mvg := range mvp.oldGroups {
-                if mvg.IsStatic {
-                        staticChannels, _ := mvg.getAllChannels()
-                        channelList = append(channelList, staticChannels...)
-                }
-        }
-        if len(channelList) > 0 {
-                containsStatic = true
-        }
-        return channelList, containsStatic
+	channelList := []net.IP{}
+	containsStatic := false
+	for _, mvg := range mvp.oldGroups {
+		if mvg.IsStatic {
+			staticChannels, _ := mvg.getAllChannels()
+			channelList = append(channelList, staticChannels...)
+		}
+	}
+	if len(channelList) > 0 {
+		containsStatic = true
+	}
+	return channelList, containsStatic
 }
 
-//getAllChannels - Returns all channels in the Mvlan Profile
+// getAllChannels - Returns all channels in the Mvlan Profile
 func (mvg *MvlanGroup) getAllChannels() ([]net.IP, bool) {
-        channelList := []net.IP{}
+	channelList := []net.IP{}
 
-        if mvg == nil || len(mvg.McIPs) == 0 {
-                return []net.IP{}, false
-        }
+	if mvg == nil || len(mvg.McIPs) == 0 {
+		return []net.IP{}, false
+	}
 
-        grpChannelOrRange := mvg.McIPs
-        for _, channelOrRange := range grpChannelOrRange {
-                if strings.Contains(channelOrRange, "-") {
-                        var splits = strings.Split(channelOrRange, "-")
-                        ipStart := util.IP2LongConv(net.ParseIP(splits[0]))
-                        ipEnd := util.IP2LongConv(net.ParseIP(splits[1]))
+	grpChannelOrRange := mvg.McIPs
+	for _, channelOrRange := range grpChannelOrRange {
+		if strings.Contains(channelOrRange, "-") {
+			var splits = strings.Split(channelOrRange, "-")
+			ipStart := util.IP2LongConv(net.ParseIP(splits[0]))
+			ipEnd := util.IP2LongConv(net.ParseIP(splits[1]))
 
-                        for i := ipStart; i <= ipEnd; i++ {
-                                channelList = append(channelList, util.Long2ipConv(i))
-                        }
-                } else {
-                        channelList = append(channelList, net.ParseIP(channelOrRange))
-                }
-        }
-        return channelList, true
+			for i := ipStart; i <= ipEnd; i++ {
+				channelList = append(channelList, util.Long2ipConv(i))
+			}
+		} else {
+			channelList = append(channelList, net.ParseIP(channelOrRange))
+		}
+	}
+	return channelList, true
 }
 
-//SetUpdateStatus - Sets profile update status for devices
+// SetUpdateStatus - Sets profile update status for devices
 func (mvp *MvlanProfile) SetUpdateStatus(serialNum string, status OperInProgress) {
-        if serialNum != "" {
-                mvp.DevicesList[serialNum] = status
-                return
-        }
+	if serialNum != "" {
+		mvp.DevicesList[serialNum] = status
+		return
+	}
 
-        for srNo := range mvp.DevicesList {
-                mvp.DevicesList[srNo] = status
-        }
+	for srNo := range mvp.DevicesList {
+		mvp.DevicesList[srNo] = status
+	}
 }
 
-//isUpdateInProgress - checking is update is in progress for the mvlan profile
+// isUpdateInProgress - checking is update is in progress for the mvlan profile
 func (mvp *MvlanProfile) isUpdateInProgress() bool {
-
-        for srNo := range mvp.DevicesList {
-                if mvp.DevicesList[srNo] == UpdateInProgress {
-                        return true
-                }
-        }
-        return false
+	for srNo := range mvp.DevicesList {
+		if mvp.DevicesList[srNo] == UpdateInProgress {
+			return true
+		}
+	}
+	return false
 }
 
-//IsUpdateInProgressForDevice - Checks is Mvlan Profile update is is progress for the given device
+// IsUpdateInProgressForDevice - Checks is Mvlan Profile update is is progress for the given device
 func (mvp *MvlanProfile) IsUpdateInProgressForDevice(device string) bool {
-        if vd := GetApplication().GetDevice(device); vd != nil {
-                if mvp.DevicesList[vd.SerialNum] == UpdateInProgress {
-                        return true
-                }
-        }
-        return false
+	if vd := GetApplication().GetDevice(device); vd != nil {
+		if mvp.DevicesList[vd.SerialNum] == UpdateInProgress {
+			return true
+		}
+	}
+	return false
 }
 
 // DelFromDb to delere mvlan from database
 func (mvp *MvlanProfile) DelFromDb(cntx context.Context) {
-        _ = db.DelMvlan(cntx, uint16(mvp.Mvlan))
+	_ = db.DelMvlan(cntx, uint16(mvp.Mvlan))
 }
 
-//DelFlows - Triggers flow deletion after registering for flow indication event
+// DelFlows - Triggers flow deletion after registering for flow indication event
 func (mvp *MvlanProfile) DelFlows(cntx context.Context, device *VoltDevice, flow *of.VoltFlow) error {
-        mvp.mvpFlowLock.Lock()
-        defer mvp.mvpFlowLock.Unlock()
+	mvp.mvpFlowLock.Lock()
+	defer mvp.mvpFlowLock.Unlock()
 
-        var flowMap map[string]bool
-        var ok bool
+	var flowMap map[string]bool
+	var ok bool
 
-        for cookie := range flow.SubFlows {
-                cookie := strconv.FormatUint(cookie, 10)
-                fe := &FlowEvent{
-                        eType:     EventTypeMcastFlowRemoved,
-                        device:    device.Name,
-                        cookie:    cookie,
-                        eventData: mvp,
-                }
-                device.RegisterFlowDelEvent(cookie, fe)
+	for cookie := range flow.SubFlows {
+		cookie := strconv.FormatUint(cookie, 10)
+		fe := &FlowEvent{
+			eType:     EventTypeMcastFlowRemoved,
+			device:    device.Name,
+			cookie:    cookie,
+			eventData: mvp,
+		}
+		device.RegisterFlowDelEvent(cookie, fe)
 
-                if flowMap, ok = mvp.PendingDeleteFlow[device.Name]; !ok {
-                        flowMap = make(map[string]bool)
-                }
-                flowMap[cookie] = true
-                mvp.PendingDeleteFlow[device.Name] = flowMap
-        }
-        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)
+		if flowMap, ok = mvp.PendingDeleteFlow[device.Name]; !ok {
+			flowMap = make(map[string]bool)
+		}
+		flowMap[cookie] = true
+		mvp.PendingDeleteFlow[device.Name] = flowMap
+	}
+	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)
 }
 
-//FlowRemoveSuccess - Process flow success indication
+// FlowRemoveSuccess - Process flow success indication
 func (mvp *MvlanProfile) FlowRemoveSuccess(cntx context.Context, cookie string, device string) {
-        mvp.mvpFlowLock.Lock()
-        defer mvp.mvpFlowLock.Unlock()
+	mvp.mvpFlowLock.Lock()
+	defer mvp.mvpFlowLock.Unlock()
 
-        logger.Infow(ctx, "Mvlan Flow Remove Success Notification", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "Device": device})
+	logger.Infow(ctx, "Mvlan Flow Remove Success Notification", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "Device": device})
 
-        if _, ok := mvp.PendingDeleteFlow[device]; ok {
-                delete(mvp.PendingDeleteFlow[device], cookie)
-        }
+	if _, ok := mvp.PendingDeleteFlow[device]; ok {
+		delete(mvp.PendingDeleteFlow[device], cookie)
+	}
 
-        if err := mvp.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
-        }
+	if err := mvp.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
+	}
 }
 
-//FlowRemoveFailure - Process flow failure indication
+// FlowRemoveFailure - Process flow failure indication
 func (mvp *MvlanProfile) FlowRemoveFailure(cookie string, device string, errorCode uint32, errReason string) {
+	mvp.mvpFlowLock.Lock()
+	defer mvp.mvpFlowLock.Unlock()
 
-        mvp.mvpFlowLock.Lock()
-        defer mvp.mvpFlowLock.Unlock()
-
-        if flowMap, ok := mvp.PendingDeleteFlow[device]; ok {
-                if _, ok := flowMap[cookie]; ok {
-                        logger.Errorw(ctx, "Mvlan Flow Remove Failure Notification", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "ErrorCode": errorCode, "ErrorReason": errReason, "Device": device})
-                        return
-                }
-        }
-        logger.Errorw(ctx, "Mvlan Flow Del Failure Notification for Unknown cookie", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "ErrorCode": errorCode, "ErrorReason": errReason})
-
+	if flowMap, ok := mvp.PendingDeleteFlow[device]; ok {
+		if _, ok := flowMap[cookie]; ok {
+			logger.Errorw(ctx, "Mvlan Flow Remove Failure Notification", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "ErrorCode": errorCode, "ErrorReason": errReason, "Device": device})
+			return
+		}
+	}
+	logger.Errorw(ctx, "Mvlan Flow Del Failure Notification for Unknown cookie", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "ErrorCode": errorCode, "ErrorReason": errReason})
 }
 
 // IsStaticGroup to check if group is static
 func (mvp *MvlanProfile) IsStaticGroup(groupName string) bool {
-        return mvp.Groups[groupName].IsStatic
+	return mvp.Groups[groupName].IsStatic
 }
 
 // generateGroupKey to generate group key
 func (mvp *MvlanProfile) generateGroupKey(name string, ipAddr string) string {
-        if mvp.IsChannelBasedGroup {
-                return mvp.Mvlan.String() + "_" + ipAddr
-        }
-        return mvp.Mvlan.String() + "_" + name
+	if mvp.IsChannelBasedGroup {
+		return mvp.Mvlan.String() + "_" + ipAddr
+	}
+	return mvp.Mvlan.String() + "_" + name
 }
 
 // GetStaticGroupName to get static igmp group
 func (mvp *MvlanProfile) GetStaticGroupName(gip net.IP) string {
-        for _, mvg := range mvp.Groups {
-                if mvg.IsStatic {
-                        if doesIPMatch(gip, mvg.McIPs) {
-                                return mvg.Name
-                        }
-                }
-        }
-        return ""
+	for _, mvg := range mvp.Groups {
+		if mvg.IsStatic {
+			if doesIPMatch(gip, mvg.McIPs) {
+				return mvg.Name
+			}
+		}
+	}
+	return ""
 }
 
 // GetStaticIgmpGroup to get static igmp group
 func (mvp *MvlanProfile) GetStaticIgmpGroup(gip net.IP) *IgmpGroup {
-
-        staticGroupName := mvp.GetStaticGroupName(gip)
-        grpKey := mvp.generateGroupKey(staticGroupName, gip.String())
-        logger.Debugw(ctx, "Get Static IGMP Group", log.Fields{"Group": grpKey})
-        ig, ok := GetApplication().IgmpGroups.Load(grpKey)
-        if ok {
-                logger.Debugw(ctx, "Get Static IGMP Group Success", log.Fields{"Group": grpKey})
-                return ig.(*IgmpGroup)
-        }
-        return nil
+	staticGroupName := mvp.GetStaticGroupName(gip)
+	grpKey := mvp.generateGroupKey(staticGroupName, gip.String())
+	logger.Debugw(ctx, "Get Static IGMP Group", log.Fields{"Group": grpKey})
+	ig, ok := GetApplication().IgmpGroups.Load(grpKey)
+	if ok {
+		logger.Debugw(ctx, "Get Static IGMP Group Success", log.Fields{"Group": grpKey})
+		return ig.(*IgmpGroup)
+	}
+	return nil
 }
 
-//pushIgmpMcastFlows - Adds all IGMP related flows (generic DS flow & static group flows)
+// pushIgmpMcastFlows - Adds all IGMP related flows (generic DS flow & static group flows)
 func (mvp *MvlanProfile) pushIgmpMcastFlows(cntx context.Context, OLTSerialNum string) {
+	mvp.mvpLock.RLock()
+	defer mvp.mvpLock.RUnlock()
 
-        mvp.mvpLock.RLock()
-        defer mvp.mvpLock.RUnlock()
+	if mvp.DevicesList[OLTSerialNum] == Nil {
+		logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": OLTSerialNum, "Mvlan": mvp.Mvlan})
+		return
+	}
 
-        if mvp.DevicesList[OLTSerialNum] == Nil {
-                logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": OLTSerialNum, "Mvlan": mvp.Mvlan})
-                return
-        }
+	d, _ := GetApplication().GetDeviceBySerialNo(OLTSerialNum)
+	if d == nil {
+		logger.Warnw(ctx, "Skipping Igmp & Mcast Flow processing: Device Not Found", log.Fields{"Device_SrNo": OLTSerialNum, "Mvlan": mvp.Mvlan})
+		return
+	}
 
-        d, _ := GetApplication().GetDeviceBySerialNo(OLTSerialNum)
-        if d == nil {
-                logger.Warnw(ctx, "Skipping Igmp & Mcast Flow processing: Device Not Found", log.Fields{"Device_SrNo": OLTSerialNum, "Mvlan": mvp.Mvlan})
-                return
-        }
+	p := d.GetPort(d.NniPort)
 
-        p := d.GetPort(d.NniPort)
+	if p != nil && p.State == PortStateUp {
+		logger.Infow(ctx, "NNI Port Status is: UP & Vlan Enabled", log.Fields{"Device": d, "port": p})
 
-        if p != nil && p.State == PortStateUp {
-                logger.Infow(ctx, "NNI Port Status is: UP & Vlan Enabled", log.Fields{"Device": d, "port": p})
+		//Push Igmp DS Control Flows
+		err := mvp.ApplyIgmpDSFlowForMvp(cntx, d.Name)
+		if err != nil {
+			logger.Errorw(ctx, "DS IGMP Flow Add Failed for device",
+				log.Fields{"Reason": err.Error(), "device": d.Name})
+		}
 
-                //Push Igmp DS Control Flows
-                err := mvp.ApplyIgmpDSFlowForMvp(cntx, d.Name)
-                if err != nil {
-                        logger.Errorw(ctx, "DS IGMP Flow Add Failed for device",
-                                log.Fields{"Reason": err.Error(), "device": d.Name})
-                }
-
-                //Trigger Join for static channels
-                if channelList, containsStatic := mvp.getAllStaticChannels(); containsStatic {
-                        mvp.ProcessStaticGroup(cntx, d.Name, channelList, true)
-                } else {
-                        logger.Infow(ctx, "No Static Channels Present", log.Fields{"mvp": mvp.Name, "Mvlan": mvp.Mvlan})
-                }
-        }
+		//Trigger Join for static channels
+		if channelList, containsStatic := mvp.getAllStaticChannels(); containsStatic {
+			mvp.ProcessStaticGroup(cntx, d.Name, channelList, true)
+		} else {
+			logger.Infow(ctx, "No Static Channels Present", log.Fields{"mvp": mvp.Name, "Mvlan": mvp.Mvlan})
+		}
+	}
 }
-//removeIgmpMcastFlows - Removes all IGMP related flows (generic DS flow & static group flows)
+
+// removeIgmpMcastFlows - Removes all IGMP related flows (generic DS flow & static group flows)
 func (mvp *MvlanProfile) removeIgmpMcastFlows(cntx context.Context, oltSerialNum string) {
+	mvp.mvpLock.RLock()
+	defer mvp.mvpLock.RUnlock()
 
-        mvp.mvpLock.RLock()
-        defer mvp.mvpLock.RUnlock()
+	if d, _ := GetApplication().GetDeviceBySerialNo(oltSerialNum); d != nil {
+		p := d.GetPort(d.NniPort)
+		if p != nil {
+			logger.Infow(ctx, "NNI Port Status is: UP", log.Fields{"Device": d, "port": p})
 
-        if d, _ := GetApplication().GetDeviceBySerialNo(oltSerialNum); d != nil {
-                p := d.GetPort(d.NniPort)
-                if p != nil {
-                        logger.Infow(ctx, "NNI Port Status is: UP", log.Fields{"Device": d, "port": p})
+			// ***Do not change the order***
+			// When Vlan is disabled, the process end is determined by the DS Igmp flag in device
 
-                        // ***Do not change the order***
-                        // When Vlan is disabled, the process end is determined by the DS Igmp flag in device
+			//Trigger Leave for static channels
+			if channelList, containsStatic := mvp.getAllStaticChannels(); containsStatic {
+				mvp.ProcessStaticGroup(cntx, d.Name, channelList, false)
+			} else {
+				logger.Infow(ctx, "No Static Channels Present", log.Fields{"mvp": mvp.Name, "Mvlan": mvp.Mvlan})
+			}
 
-                        //Trigger Leave for static channels
-                        if channelList, containsStatic := mvp.getAllStaticChannels(); containsStatic {
-                                mvp.ProcessStaticGroup(cntx, d.Name, channelList, false)
-                        } else {
-                                logger.Infow(ctx, "No Static Channels Present", log.Fields{"mvp": mvp.Name, "Mvlan": mvp.Mvlan})
-                        }
+			//Remove all dynamic members for the Mvlan Profile
+			GetApplication().IgmpGroups.Range(func(key, value interface{}) bool {
+				ig := value.(*IgmpGroup)
+				if ig.Mvlan == mvp.Mvlan {
+					igd := ig.Devices[d.Name]
+					ig.DelIgmpGroupDevice(cntx, igd)
+					if ig.NumDevicesActive() == 0 {
+						GetApplication().DelIgmpGroup(cntx, ig)
+					}
+				}
+				return true
+			})
 
-                        //Remove all dynamic members for the Mvlan Profile
-                        GetApplication().IgmpGroups.Range(func(key, value interface{}) bool {
-                                ig := value.(*IgmpGroup)
-                                if ig.Mvlan == mvp.Mvlan {
-                                        igd := ig.Devices[d.Name]
-                                        ig.DelIgmpGroupDevice(cntx, igd)
-                                        if ig.NumDevicesActive() == 0 {
-                                                GetApplication().DelIgmpGroup(cntx, ig)
-                                        }
-                                }
-                                return true
-                        })
-
-                        //Remove DS Igmp trap flow
-                        err := mvp.RemoveIgmpDSFlowForMvp(cntx, d.Name)
-                        if err != nil {
-                                logger.Errorw(ctx, "DS IGMP Flow Del Failed", log.Fields{"Reason": err.Error(), "device": d.Name})
-                        }
-                }
-        }
+			//Remove DS Igmp trap flow
+			err := mvp.RemoveIgmpDSFlowForMvp(cntx, d.Name)
+			if err != nil {
+				logger.Errorw(ctx, "DS IGMP Flow Del Failed", log.Fields{"Reason": err.Error(), "device": d.Name})
+			}
+		}
+	}
 }
 
 // ApplyIgmpDSFlowForMvp to apply Igmp DS flow for mvlan.
 func (mvp *MvlanProfile) ApplyIgmpDSFlowForMvp(cntx context.Context, device string) error {
-        va := GetApplication()
-        dIntf, ok := va.DevicesDisc.Load(device)
-        if !ok {
-                return errors.New("Device Doesn't Exist")
-        }
-        d := dIntf.(*VoltDevice)
-        mvlan := mvp.Mvlan
+	va := GetApplication()
+	dIntf, ok := va.DevicesDisc.Load(device)
+	if !ok {
+		return errors.New("Device Doesn't Exist")
+	}
+	d := dIntf.(*VoltDevice)
+	mvlan := mvp.Mvlan
 
-        flowAlreadyApplied, ok := d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)]
-        if !ok || !flowAlreadyApplied {
-                flows, err := mvp.BuildIgmpDSFlows(device)
-                if err == nil {
-                        err = cntlr.GetController().AddFlows(cntx, d.NniPort, device, flows)
-                        if err != nil {
-                                logger.Warnw(ctx, "Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
-                                return err
-                        }
-                        d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)] = true
-                        logger.Infow(ctx, "Updating voltDevice that IGMP DS flow as \"added\" for ",
-                                log.Fields{"device": d.SerialNum, "mvlan": mvlan})
-                } else {
-                        logger.Errorw(ctx, "DS IGMP Flow Add Failed", log.Fields{"Reason": err.Error(), "Mvlan": mvlan})
-                }
-        }
+	flowAlreadyApplied, ok := d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)]
+	if !ok || !flowAlreadyApplied {
+		flows, err := mvp.BuildIgmpDSFlows(device)
+		if err == nil {
+			err = cntlr.GetController().AddFlows(cntx, d.NniPort, device, flows)
+			if err != nil {
+				logger.Warnw(ctx, "Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
+				return err
+			}
+			d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)] = true
+			logger.Infow(ctx, "Updating voltDevice that IGMP DS flow as \"added\" for ",
+				log.Fields{"device": d.SerialNum, "mvlan": mvlan})
+		} else {
+			logger.Errorw(ctx, "DS IGMP Flow Add Failed", log.Fields{"Reason": err.Error(), "Mvlan": mvlan})
+		}
+	}
 
-        return nil
+	return nil
 }
 
 // RemoveIgmpDSFlowForMvp to remove Igmp DS flow for mvlan.
 func (mvp *MvlanProfile) RemoveIgmpDSFlowForMvp(cntx context.Context, device string) error {
+	va := GetApplication()
+	mvlan := mvp.Mvlan
 
-        va := GetApplication()
-        mvlan := mvp.Mvlan
+	dIntf, ok := va.DevicesDisc.Load(device)
+	if !ok {
+		return errors.New("Device Doesn't Exist")
+	}
+	d := dIntf.(*VoltDevice)
+	/* No need of strict check during DS IGMP deletion
+	   flowAlreadyApplied, ok := d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)]
+	   if ok && flowAlreadyApplied
+	*/
+	flows, err := mvp.BuildIgmpDSFlows(device)
+	if err == nil {
+		flows.ForceAction = true
 
-        dIntf, ok := va.DevicesDisc.Load(device)
-        if !ok {
-                return errors.New("Device Doesn't Exist")
-        }
-        d := dIntf.(*VoltDevice)
-        /* No need of strict check during DS IGMP deletion
-        flowAlreadyApplied, ok := d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)]
-        if ok && flowAlreadyApplied
-        */
-        flows, err := mvp.BuildIgmpDSFlows(device)
-        if err == nil {
-                flows.ForceAction = true
+		err = mvp.DelFlows(cntx, d, flows)
+		if err != nil {
+			logger.Warnw(ctx, "De-Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
+			return err
+		}
+		d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)] = false
+		logger.Infow(ctx, "Updating voltDevice that IGMP DS flow as \"removed\" for ",
+			log.Fields{"device": d.SerialNum, "mvlan": mvlan})
+	} else {
+		logger.Errorw(ctx, "DS IGMP Flow Del Failed", log.Fields{"Reason": err.Error()})
+	}
 
-                err = mvp.DelFlows(cntx, d, flows)
-                if err != nil {
-                        logger.Warnw(ctx, "De-Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
-                        return err
-                }
-                d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)] = false
-                logger.Infow(ctx, "Updating voltDevice that IGMP DS flow as \"removed\" for ",
-                        log.Fields{"device": d.SerialNum, "mvlan": mvlan})
-        } else {
-                logger.Errorw(ctx, "DS IGMP Flow Del Failed", log.Fields{"Reason": err.Error()})
-        }
-
-        return nil
+	return nil
 }
 
 // BuildIgmpDSFlows to build Igmp DS flows for NNI port
 func (mvp *MvlanProfile) BuildIgmpDSFlows(device string) (*of.VoltFlow, error) {
-        dIntf, ok := GetApplication().DevicesDisc.Load(device)
-        if !ok {
-                return nil, errors.New("Device Doesn't Exist")
-        }
-        d := dIntf.(*VoltDevice)
+	dIntf, ok := GetApplication().DevicesDisc.Load(device)
+	if !ok {
+		return nil, errors.New("Device Doesn't Exist")
+	}
+	d := dIntf.(*VoltDevice)
 
-        logger.Infow(ctx, "Building DS IGMP Flow for NNI port", log.Fields{"vs": d.NniPort, "Mvlan": mvp.Mvlan})
-        flow := &of.VoltFlow{}
-        flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
-        subFlow := of.NewVoltSubFlow()
-        subFlow.SetTableID(0)
-        subFlow.SetMatchVlan(mvp.Mvlan)
+	logger.Infow(ctx, "Building DS IGMP Flow for NNI port", log.Fields{"vs": d.NniPort, "Mvlan": mvp.Mvlan})
+	flow := &of.VoltFlow{}
+	flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
+	subFlow := of.NewVoltSubFlow()
+	subFlow.SetTableID(0)
+	subFlow.SetMatchVlan(mvp.Mvlan)
 
-        nniPort, err := GetApplication().GetNniPort(device)
-        if err != nil {
-                return nil, err
-        }
-        nniPortID, err1 := GetApplication().GetPortID(nniPort)
-        if err1 != nil {
-                return nil, errors.New("Unknown NNI outport")
-        }
-        subFlow.SetInPort(nniPortID)
-        subFlow.SetIgmpMatch()
-        subFlow.SetReportToController()
-        subFlow.Cookie = uint64(nniPortID)<<32 | uint64(mvp.Mvlan)
-        subFlow.Priority = of.IgmpFlowPriority
+	nniPort, err := GetApplication().GetNniPort(device)
+	if err != nil {
+		return nil, err
+	}
+	nniPortID, err1 := GetApplication().GetPortID(nniPort)
+	if err1 != nil {
+		return nil, errors.New("Unknown NNI outport")
+	}
+	subFlow.SetInPort(nniPortID)
+	subFlow.SetIgmpMatch()
+	subFlow.SetReportToController()
+	subFlow.Cookie = uint64(nniPortID)<<32 | uint64(mvp.Mvlan)
+	subFlow.Priority = of.IgmpFlowPriority
 
-        flow.SubFlows[subFlow.Cookie] = subFlow
-        logger.Infow(ctx, "Built DS IGMP flow", log.Fields{"cookie": subFlow.Cookie, "subflow": subFlow})
-        return flow, nil
+	flow.SubFlows[subFlow.Cookie] = subFlow
+	logger.Infow(ctx, "Built DS IGMP flow", log.Fields{"cookie": subFlow.Cookie, "subflow": subFlow})
+	return flow, nil
 }
 
-//updateStaticGroups - Generates static joins & leaves for newly added and removed static channels respectively
+// updateStaticGroups - Generates static joins & leaves for newly added and removed static channels respectively
 func (mvp *MvlanProfile) updateStaticGroups(cntx context.Context, deviceID string, added []net.IP, removed []net.IP) {
+	// Update static group configs for all associated devices
+	updateGroups := func(key interface{}, value interface{}) bool {
+		d := value.(*VoltDevice)
 
-        //Update static group configs for all associated devices
-        updateGroups := func(key interface{}, value interface{}) bool {
-                d := value.(*VoltDevice)
+		if mvp.DevicesList[d.SerialNum] == Nil {
+			logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": d, "Profile Device List": mvp.DevicesList})
+			return true
+		}
+		// TODO if mvp.IsChannelBasedGroup {
+		mvp.ProcessStaticGroup(cntx, d.Name, added, true)
+		mvp.ProcessStaticGroup(cntx, d.Name, removed, false)
+		//}
+		return true
+	}
 
-                if mvp.DevicesList[d.SerialNum] == Nil {
-                        logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": d, "Profile Device List": mvp.DevicesList})
-                        return true
-                }
-                //TODO if mvp.IsChannelBasedGroup {
-                mvp.ProcessStaticGroup(cntx, d.Name, added, true)
-                mvp.ProcessStaticGroup(cntx, d.Name, removed, false)
-                //}
-                return true
-        }
-
-        if deviceID != "" {
-                vd := GetApplication().GetDevice(deviceID)
-                updateGroups(deviceID, vd)
-        } else {
-                GetApplication().DevicesDisc.Range(updateGroups)
-        }
+	if deviceID != "" {
+		vd := GetApplication().GetDevice(deviceID)
+		updateGroups(deviceID, vd)
+	} else {
+		GetApplication().DevicesDisc.Range(updateGroups)
+	}
 }
 
-//updateDynamicGroups - Generates joins with updated sources for existing channels
+// updateDynamicGroups - Generates joins with updated sources for existing channels
 func (mvp *MvlanProfile) updateDynamicGroups(cntx context.Context, deviceID string, added []net.IP, removed []net.IP) {
+	//mvlan := mvp.Mvlan
+	va := GetApplication()
 
-        //mvlan := mvp.Mvlan
-        va := GetApplication()
+	updateGroups := func(key interface{}, value interface{}) bool {
+		d := value.(*VoltDevice)
 
-        updateGroups := func(key interface{}, value interface{}) bool {
-                d := value.(*VoltDevice)
+		if mvp.DevicesList[d.SerialNum] == Nil {
+			logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": d, "Profile Device List": mvp.DevicesList})
+			return true
+		}
+		for _, groupAddr := range added {
+			_, gName := va.GetMvlanProfileForMcIP(mvp.Name, groupAddr)
+			grpKey := mvp.generateGroupKey(gName, groupAddr.String())
+			logger.Debugw(ctx, "IGMP Group", log.Fields{"Group": grpKey, "groupAddr": groupAddr})
+			if igIntf, ok := va.IgmpGroups.Load(grpKey); ok {
+				ig := igIntf.(*IgmpGroup)
+				if igd, ok := ig.getIgmpGroupDevice(cntx, d.Name); ok {
+					if igcIntf, ok := igd.GroupChannels.Load(groupAddr.String()); ok {
+						igc := igcIntf.(*IgmpGroupChannel)
+						incl := false
+						var ip []net.IP
+						var groupModified = false
+						if _, ok := mvp.Proxy[igc.GroupName]; ok {
+							if mvp.Proxy[igc.GroupName].Mode == common.Include {
+								incl = true
+							}
+							ip = mvp.Proxy[igc.GroupName].SourceList
+						}
+						for port, igp := range igc.NewReceivers {
+							// Process the include/exclude list which may end up modifying the group
+							if change, _ := igc.ProcessSources(cntx, port, ip, incl); change {
+								groupModified = true
+							}
+							igc.ProcessMode(port, incl)
 
-                if mvp.DevicesList[d.SerialNum] == Nil {
-                        logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": d, "Profile Device List": mvp.DevicesList})
-                        return true
-                }
-                for _, groupAddr := range added {
+							if err := igp.WriteToDb(cntx, igc.Mvlan, igc.GroupAddr, igc.Device); err != nil {
+								logger.Errorw(ctx, "Igmp group port Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
+							}
+						}
+						// If the group is modified as this is the first receiver or due to include/exclude list modification
+						// send a report to the upstream multicast servers
+						if groupModified {
+							logger.Debug(ctx, "Group Modified and IGMP report sent to the upstream server")
+							igc.SendReport(false)
+						}
+						if err := igc.WriteToDb(cntx); err != nil {
+							logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
+						}
+					}
+				}
+			}
+		}
 
-                        _, gName := va.GetMvlanProfileForMcIP(mvp.Name, groupAddr)
-                        grpKey := mvp.generateGroupKey(gName, groupAddr.String())
-                        logger.Debugw(ctx, "IGMP Group", log.Fields{"Group": grpKey, "groupAddr": groupAddr})
-                        if igIntf, ok := va.IgmpGroups.Load(grpKey); ok {
-                                ig := igIntf.(*IgmpGroup)
-                                if igd, ok := ig.getIgmpGroupDevice(cntx, d.Name); ok {
-                                        if igcIntf, ok := igd.GroupChannels.Load(groupAddr.String()); ok {
-                                                igc := igcIntf.(*IgmpGroupChannel)
-                                                incl := false
-                                                var ip []net.IP
-                                                var groupModified = false
-                                                if _, ok := mvp.Proxy[igc.GroupName]; ok {
-                                                        if mvp.Proxy[igc.GroupName].Mode == common.Include {
-                                                                incl = true
-                                                        }
-                                                        ip = mvp.Proxy[igc.GroupName].SourceList
-                                                }
-                                                for port, igp := range igc.NewReceivers {
-                                                        // Process the include/exclude list which may end up modifying the group
-                                                        if change, _ := igc.ProcessSources(cntx, port, ip, incl); change {
-                                                                groupModified = true
-                                                        }
-                                                        igc.ProcessMode(port, incl)
+		return true
+	}
 
-                                                        if err := igp.WriteToDb(cntx, igc.Mvlan, igc.GroupAddr, igc.Device); err != nil {
-                                                                logger.Errorw(ctx, "Igmp group port Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
-                                                        }
-                                                }
-                                                // If the group is modified as this is the first receiver or due to include/exclude list modification
-                                                // send a report to the upstream multicast servers
-                                                if groupModified {
-                                                        logger.Debug(ctx, "Group Modified and IGMP report sent to the upstream server")
-                                                        igc.SendReport(false)
-                                                }
-                                                if err := igc.WriteToDb(cntx); err != nil {
-                                                        logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
-                                                }
-                                        }
-                                }
-                        }
-                }
-
-                return true
-        }
-
-        if deviceID != "" {
-                vd := GetApplication().GetDevice(deviceID)
-                updateGroups(deviceID, vd)
-        } else {
-                GetApplication().DevicesDisc.Range(updateGroups)
-        }
+	if deviceID != "" {
+		vd := GetApplication().GetDevice(deviceID)
+		updateGroups(deviceID, vd)
+	} else {
+		GetApplication().DevicesDisc.Range(updateGroups)
+	}
 }
 
-//GroupsUpdated - Handles removing of Igmp Groups, flows & group table entries for
-//channels removed as part of update
+// GroupsUpdated - Handles removing of Igmp Groups, flows & group table entries for
+// channels removed as part of update
 func (mvp *MvlanProfile) GroupsUpdated(cntx context.Context, deviceID string) {
+	deleteChannelIfRemoved := func(key interface{}, value interface{}) bool {
+		ig := value.(*IgmpGroup)
 
-        deleteChannelIfRemoved := func(key interface{}, value interface{}) bool {
-                ig := value.(*IgmpGroup)
+		if ig.Mvlan != mvp.Mvlan {
+			return true
+		}
+		grpName := ig.GroupName
+		logger.Infow(ctx, "###Update Cycle", log.Fields{"IG": ig.GroupName, "Addr": ig.GroupAddr})
+		// Check if group exists and remove the entire group object otherwise
+		if currentChannels := mvp.Groups[grpName]; currentChannels != nil {
+			if mvp.IsChannelBasedGroup {
+				channelPresent := doesIPMatch(ig.GroupAddr, currentChannels.McIPs)
+				if channelPresent || mvp.isChannelStatic(ig.GroupAddr) {
+					return true
+				}
+			} else {
+				allExistingChannels := ig.GetAllIgmpChannelForDevice(deviceID)
+				for channel := range allExistingChannels {
+					channelIP := net.ParseIP(channel)
+					channelPresent := mvp.IsChannelPresent(channelIP, currentChannels.McIPs, mvp.IsStaticGroup(ig.GroupName))
+					if channelPresent {
+						staticChannel := mvp.isChannelStatic(channelIP)
+						logger.Infow(ctx, "###Channel Comparison", log.Fields{"staticChannel": staticChannel, "Group": mvp.IsStaticGroup(ig.GroupName), "Channel": channel})
+						// Logic:
+						// If channel is Static & existing Group is also static - No migration required
+						// If channel is not Static & existing Group is also not static - No migration required
 
-                if ig.Mvlan != mvp.Mvlan {
-                        return true
-                }
-                grpName := ig.GroupName
-                logger.Infow(ctx, "###Update Cycle", log.Fields{"IG": ig.GroupName, "Addr": ig.GroupAddr})
-                //Check if group exists and remove the entire group object otherwise
-                if currentChannels := mvp.Groups[grpName]; currentChannels != nil {
+						// If channel is Static and existing Group is not static - Migrate (from dynamic to static)
+						// (Channel already part of dynamic, added to static)
 
-                        if mvp.IsChannelBasedGroup {
-                                channelPresent := doesIPMatch(ig.GroupAddr, currentChannels.McIPs)
-                                if channelPresent || mvp.isChannelStatic(ig.GroupAddr) {
-                                        return true
-                                }
-                        } else {
-                                allExistingChannels := ig.GetAllIgmpChannelForDevice(deviceID)
-                                for channel := range allExistingChannels {
-                                        channelIP := net.ParseIP(channel)
-                                        channelPresent := mvp.IsChannelPresent(channelIP, currentChannels.McIPs, mvp.IsStaticGroup(ig.GroupName))
-                                        if channelPresent {
-                                                staticChannel := mvp.isChannelStatic(channelIP)
-                                                logger.Infow(ctx, "###Channel Comparision", log.Fields{"staticChannel": staticChannel, "Group": mvp.IsStaticGroup(ig.GroupName), "Channel": channel})
-                                                // Logic:
-                                                // If channel is Static & existing Group is also static - No migration required
-                                                // If channel is not Static & existing Group is also not static - No migration required
-
-                                                // If channel is Static and existing Group is not static - Migrate (from dynamic to static)
-                                                //    (Channel already part of dynamic, added to static)
-
-                                                // If channel is not Static but existing Group is static - Migrate (from static to dynamic)
-                                                //    (Channel removed from satic but part of dynamic)
-                                                if (staticChannel != mvp.IsStaticGroup(ig.GroupName)) || (ig.IsGroupStatic != mvp.IsStaticGroup(ig.GroupName)) { // Equivalent of XOR
-                                                        ig.HandleGroupMigration(cntx, deviceID, channelIP)
-                                                } else {
-                                                        if (ig.IsGroupStatic) && mvp.IsStaticGroup(ig.GroupName) {
-                                                                if ig.GroupName != mvp.GetStaticGroupName(channelIP) {
-                                                                        ig.HandleGroupMigration(cntx, deviceID, channelIP)
-                                                                }
-                                                        }
-                                                        continue
-                                                }
-                                        } else {
-                                                logger.Debugw(ctx, "Channel Removed", log.Fields{"Channel": channel, "Group": grpName})
-                                                ig.DelIgmpChannel(cntx, deviceID, net.ParseIP(channel))
-                                                if ig.NumDevicesActive() == 0 {
-                                                        GetApplication().DelIgmpGroup(cntx, ig)
-                                                }
-                                        }
-                                }
-                                ig.IsGroupStatic = mvp.IsStaticGroup(ig.GroupName)
-                                if err := ig.WriteToDb(cntx); err != nil {
-                                        logger.Errorw(ctx, "Igmp group Write to DB failed", log.Fields{"groupName": ig.GroupName})
-                                }
-                                return true
-                        }
-                }
-                logger.Debugw(ctx, "Group Removed", log.Fields{"Channel": ig.GroupAddr, "Group": grpName, "ChannelBasedGroup": ig.IsChannelBasedGroup})
-                ig.DelIgmpGroup(cntx)
-                logger.Debugw(ctx, "Removed Igmp Group", log.Fields{"Channel": ig.GroupAddr, "Group": grpName})
-                return true
-        }
-        GetApplication().IgmpGroups.Range(deleteChannelIfRemoved)
+						// If channel is not Static but existing Group is static - Migrate (from static to dynamic)
+						// (Channel removed from satic but part of dynamic)
+						if (staticChannel != mvp.IsStaticGroup(ig.GroupName)) || (ig.IsGroupStatic != mvp.IsStaticGroup(ig.GroupName)) { // Equivalent of XOR
+							ig.HandleGroupMigration(cntx, deviceID, channelIP)
+						} else {
+							if (ig.IsGroupStatic) && mvp.IsStaticGroup(ig.GroupName) {
+								if ig.GroupName != mvp.GetStaticGroupName(channelIP) {
+									ig.HandleGroupMigration(cntx, deviceID, channelIP)
+								}
+							}
+							continue
+						}
+					} else {
+						logger.Debugw(ctx, "Channel Removed", log.Fields{"Channel": channel, "Group": grpName})
+						ig.DelIgmpChannel(cntx, deviceID, net.ParseIP(channel))
+						if ig.NumDevicesActive() == 0 {
+							GetApplication().DelIgmpGroup(cntx, ig)
+						}
+					}
+				}
+				ig.IsGroupStatic = mvp.IsStaticGroup(ig.GroupName)
+				if err := ig.WriteToDb(cntx); err != nil {
+					logger.Errorw(ctx, "Igmp group Write to DB failed", log.Fields{"groupName": ig.GroupName})
+				}
+				return true
+			}
+		}
+		logger.Debugw(ctx, "Group Removed", log.Fields{"Channel": ig.GroupAddr, "Group": grpName, "ChannelBasedGroup": ig.IsChannelBasedGroup})
+		ig.DelIgmpGroup(cntx)
+		logger.Debugw(ctx, "Removed Igmp Group", log.Fields{"Channel": ig.GroupAddr, "Group": grpName})
+		return true
+	}
+	GetApplication().IgmpGroups.Range(deleteChannelIfRemoved)
 }
 
 // IsChannelPresent to check if channel is present
 func (mvp *MvlanProfile) IsChannelPresent(channelIP net.IP, groupChannelList []string, IsStaticGroup bool) bool {
-        // Only in case of static group, migration need to be supported.
-        // Dynamic to dynamic group migration not supported currently
-        if doesIPMatch(channelIP, groupChannelList) || mvp.isChannelStatic(channelIP) {
-                return true
-        } else if IsStaticGroup {
-                return (mvp.GetMvlanGroup(channelIP) != "")
-        }
+	// Only in case of static group, migration need to be supported.
+	// Dynamic to dynamic group migration not supported currently
+	if doesIPMatch(channelIP, groupChannelList) || mvp.isChannelStatic(channelIP) {
+		return true
+	} else if IsStaticGroup {
+		return (mvp.GetMvlanGroup(channelIP) != "")
+	}
 
-        return false
+	return false
 }
 
-
 // GetMvlanGroup to get mvlan group
 func (mvp *MvlanProfile) GetMvlanGroup(ip net.IP) string {
-        //Check for Static Group First
-        if mvp.containsStaticChannels() {
-                grpName := mvp.GetStaticGroupName(ip)
-                if grpName != "" {
-                        return grpName
-                }
-        }
+	// Check for Static Group First
+	if mvp.containsStaticChannels() {
+		grpName := mvp.GetStaticGroupName(ip)
+		if grpName != "" {
+			return grpName
+		}
+	}
 
-        for _, mvg := range mvp.Groups {
-                if mvg.Wildcard {
-                        return mvg.Name
-                }
-                if doesIPMatch(ip, mvg.McIPs) {
-                        return mvg.Name
-                }
-        }
-        return ""
+	for _, mvg := range mvp.Groups {
+		if mvg.Wildcard {
+			return mvg.Name
+		}
+		if doesIPMatch(ip, mvg.McIPs) {
+			return mvg.Name
+		}
+	}
+	return ""
 }
 
 // ProcessStaticGroup - Process Static Join/Leave Req for static channels
 func (mvp *MvlanProfile) ProcessStaticGroup(cntx context.Context, device string, groupAddresses []net.IP, isJoin bool) {
+	logger.Debugw(ctx, "Received Static Group Request", log.Fields{"Device": device, "Join": isJoin, "Group Address List": groupAddresses})
 
-        logger.Debugw(ctx, "Received Static Group Request", log.Fields{"Device": device, "Join": isJoin, "Group Address List": groupAddresses})
+	mvlan := mvp.Mvlan
+	va := GetApplication()
 
-        mvlan := mvp.Mvlan
-        va := GetApplication()
+	// TODO - Handle bulk add of groupAddr
+	for _, groupAddr := range groupAddresses {
+		ig := mvp.GetStaticIgmpGroup(groupAddr)
+		if isJoin {
+			vd := va.GetDevice(device)
+			igmpProf, _, _ := getIgmpProxyCfgAndIP(mvlan, vd.SerialNum)
+			ver := igmpProf.IgmpVerToServer
 
-        //TODO - Handle bulk add of groupAddr
-        for _, groupAddr := range groupAddresses {
+			if ig == nil {
+				// First time group Creation: Create the IGMP group and then add the receiver to the group
+				logger.Infow(ctx, "Static IGMP Add received for new group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
+				if ig = GetApplication().AddIgmpGroup(cntx, mvp.Name, groupAddr, device); ig != nil {
+					ig.IgmpGroupLock.Lock()
+					ig.AddReceiver(cntx, device, StaticPort, groupAddr, nil, getVersion(ver),
+						0, 0, 0xFF)
+					ig.IgmpGroupLock.Unlock()
+				} else {
+					logger.Warnw(ctx, "Static IGMP Group Creation Failed", log.Fields{"Addr": groupAddr})
+				}
+			} else {
+				// Converting existing dynamic group to static group
+				if !mvp.IsStaticGroup(ig.GroupName) {
+					ig.updateGroupName(cntx, ig.GroupName)
+				}
+				// Update case: If the IGMP group is already created. just add the receiver
+				logger.Infow(ctx, "Static IGMP Add received for existing group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
+				ig.IgmpGroupLock.Lock()
+				ig.AddReceiver(cntx, device, StaticPort, groupAddr, nil, getVersion(ver),
+					0, 0, 0xFF)
+				ig.IgmpGroupLock.Unlock()
+			}
+		} else if ig != nil {
+			logger.Infow(ctx, "Static IGMP Del received for existing group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
 
-                ig := mvp.GetStaticIgmpGroup(groupAddr)
-                if isJoin {
-                        vd := va.GetDevice(device)
-                        igmpProf, _, _ := getIgmpProxyCfgAndIP(mvlan, vd.SerialNum)
-                        ver := igmpProf.IgmpVerToServer
-
-                        if ig == nil {
-                                // First time group Creation: Create the IGMP group and then add the receiver to the group
-                                logger.Infow(ctx, "Static IGMP Add received for new group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
-                                if ig := GetApplication().AddIgmpGroup(cntx, mvp.Name, groupAddr, device); ig != nil {
-                                        ig.IgmpGroupLock.Lock()
-                                        ig.AddReceiver(cntx, device, StaticPort, groupAddr, nil, getVersion(ver),
-                                                0, 0, 0xFF)
-                                        ig.IgmpGroupLock.Unlock()
-                                } else {
-                                        logger.Warnw(ctx, "Static IGMP Group Creation Failed", log.Fields{"Addr": groupAddr})
-                                }
-                        } else {
-                                //Converting existing dynamic group to static group
-                                if !mvp.IsStaticGroup(ig.GroupName) {
-                                        ig.updateGroupName(cntx, ig.GroupName)
-                                }
-                                // Update case: If the IGMP group is already created. just add the receiver
-                                logger.Infow(ctx, "Static IGMP Add received for existing group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
-                                ig.IgmpGroupLock.Lock()
-                                ig.AddReceiver(cntx, device, StaticPort, groupAddr, nil, getVersion(ver),
-                                        0, 0, 0xFF)
-                                ig.IgmpGroupLock.Unlock()
-                        }
-                } else if ig != nil {
-                        logger.Infow(ctx, "Static IGMP Del received for existing group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
-
-                        if ig.IsChannelBasedGroup {
-                                grpName := mvp.GetMvlanGroup(ig.GroupAddr)
-                                if grpName != "" {
-                                        ig.IgmpGroupLock.Lock()
-                                        ig.DelReceiver(cntx, device, StaticPort, groupAddr, nil, 0xFF)
-                                        ig.IgmpGroupLock.Unlock()
-                                        ig.updateGroupName(cntx, grpName)
-                                } else {
-                                        ig.DelIgmpGroup(cntx)
-                                }
-                        } else {
-                                ig.IgmpGroupLock.Lock()
-                                ig.DelReceiver(cntx, device, StaticPort, groupAddr, nil, 0xFF)
-                                ig.IgmpGroupLock.Unlock()
-                        }
-                        if ig.NumDevicesActive() == 0 {
-                                GetApplication().DelIgmpGroup(cntx, ig)
-                        }
-                } else {
-                        logger.Warnw(ctx, "Static IGMP Del received for unknown group", log.Fields{"Addr": groupAddr})
-                }
-        }
+			if ig.IsChannelBasedGroup {
+				grpName := mvp.GetMvlanGroup(ig.GroupAddr)
+				if grpName != "" {
+					ig.IgmpGroupLock.Lock()
+					ig.DelReceiver(cntx, device, StaticPort, groupAddr, nil, 0xFF)
+					ig.IgmpGroupLock.Unlock()
+					ig.updateGroupName(cntx, grpName)
+				} else {
+					ig.DelIgmpGroup(cntx)
+				}
+			} else {
+				ig.IgmpGroupLock.Lock()
+				ig.DelReceiver(cntx, device, StaticPort, groupAddr, nil, 0xFF)
+				ig.IgmpGroupLock.Unlock()
+			}
+			if ig.NumDevicesActive() == 0 {
+				GetApplication().DelIgmpGroup(cntx, ig)
+			}
+		} else {
+			logger.Warnw(ctx, "Static IGMP Del received for unknown group", log.Fields{"Addr": groupAddr})
+		}
+	}
 }
 
-//getStaticChannelDiff - return the static channel newly added and removed from existing static group
+// getStaticChannelDiff - return the static channel newly added and removed from existing static group
 func (mvp *MvlanProfile) getStaticChannelDiff() (newlyAdded []net.IP, removed []net.IP, common []net.IP) {
-
-        var commonChannels []net.IP
-        newChannelList, _ := mvp.getAllStaticChannels()
-        existingChannelList, _ := mvp.getAllOldGroupStaticChannels()
-        if len(existingChannelList) == 0 {
-                return newChannelList, []net.IP{}, []net.IP{}
-        }
-        for _, newChannel := range append([]net.IP{}, newChannelList...) {
-                for _, existChannel := range append([]net.IP{}, existingChannelList...) {
-
-                        //Remove common channels between existing and new list
-                        // The remaining in the below slices give the results
-                        // Remaining in newChannelList: Newly added
-                        // Remaining in existingChannelList: Removed channels
-                        if existChannel.Equal(newChannel) {
-                                existingChannelList = removeIPFromList(existingChannelList, existChannel)
-                                newChannelList = removeIPFromList(newChannelList, newChannel)
-                                commonChannels = append(commonChannels, newChannel)
-                                logger.Infow(ctx, "#############Channel: "+existChannel.String()+" New: "+newChannel.String(), log.Fields{"Added": newChannelList, "Removed": existingChannelList})
-                                break
-                        }
-                }
-        }
-        return newChannelList, existingChannelList, commonChannels
+	var commonChannels []net.IP
+	newChannelList, _ := mvp.getAllStaticChannels()
+	existingChannelList, _ := mvp.getAllOldGroupStaticChannels()
+	if len(existingChannelList) == 0 {
+		return newChannelList, []net.IP{}, []net.IP{}
+	}
+	for _, newChannel := range append([]net.IP{}, newChannelList...) {
+		for _, existChannel := range append([]net.IP{}, existingChannelList...) {
+			// Remove common channels between existing and new list
+			// The remaining in the below slices give the results
+			// Remaining in newChannelList: Newly added
+			// Remaining in existingChannelList: Removed channels
+			if existChannel.Equal(newChannel) {
+				existingChannelList = removeIPFromList(existingChannelList, existChannel)
+				newChannelList = removeIPFromList(newChannelList, newChannel)
+				commonChannels = append(commonChannels, newChannel)
+				logger.Infow(ctx, "#############Channel: "+existChannel.String()+" New: "+newChannel.String(), log.Fields{"Added": newChannelList, "Removed": existingChannelList})
+				break
+			}
+		}
+	}
+	return newChannelList, existingChannelList, commonChannels
 }
 
-//getGroupChannelDiff - return the channel newly added and removed from existing group
+// getGroupChannelDiff - return the channel newly added and removed from existing group
 func (mvp *MvlanProfile) getGroupChannelDiff(newGroup *MvlanGroup, oldGroup *MvlanGroup) (newlyAdded []net.IP, removed []net.IP, common []net.IP) {
-
-        var commonChannels []net.IP
-        newChannelList, _ := newGroup.getAllChannels()
-        existingChannelList, _ := oldGroup.getAllChannels()
-        if len(existingChannelList) == 0 {
-                return newChannelList, []net.IP{}, []net.IP{}
-        }
-        for _, newChannel := range append([]net.IP{}, newChannelList...) {
-                for _, existChannel := range append([]net.IP{}, existingChannelList...) {
-
-                        //Remove common channels between existing and new list
-                        // The remaining in the below slices give the results
-                        // Remaining in newChannelList: Newly added
-                        // Remaining in existingChannelList: Removed channels
-                        if existChannel.Equal(newChannel) {
-                                existingChannelList = removeIPFromList(existingChannelList, existChannel)
-                                newChannelList = removeIPFromList(newChannelList, newChannel)
-                                commonChannels = append(commonChannels, newChannel)
-                                logger.Infow(ctx, "#############Channel: "+existChannel.String()+" New: "+newChannel.String(), log.Fields{"Added": newChannelList, "Removed": existingChannelList})
-                                break
-                        }
-                }
-        }
-        return newChannelList, existingChannelList, commonChannels
+	var commonChannels []net.IP
+	newChannelList, _ := newGroup.getAllChannels()
+	existingChannelList, _ := oldGroup.getAllChannels()
+	if len(existingChannelList) == 0 {
+		return newChannelList, []net.IP{}, []net.IP{}
+	}
+	for _, newChannel := range append([]net.IP{}, newChannelList...) {
+		for _, existChannel := range append([]net.IP{}, existingChannelList...) {
+			// Remove common channels between existing and new list
+			// The remaining in the below slices give the results
+			// Remaining in newChannelList: Newly added
+			// Remaining in existingChannelList: Removed channels
+			if existChannel.Equal(newChannel) {
+				existingChannelList = removeIPFromList(existingChannelList, existChannel)
+				newChannelList = removeIPFromList(newChannelList, newChannel)
+				commonChannels = append(commonChannels, newChannel)
+				logger.Infow(ctx, "#############Channel: "+existChannel.String()+" New: "+newChannel.String(), log.Fields{"Added": newChannelList, "Removed": existingChannelList})
+				break
+			}
+		}
+	}
+	return newChannelList, existingChannelList, commonChannels
 }
 
 // UpdateProfile - Updates the group & member info w.r.t the mvlan profile for the given device
 func (mvp *MvlanProfile) UpdateProfile(cntx context.Context, deviceID string) {
-        logger.Infow(ctx, "Update Mvlan Profile task triggered", log.Fields{"Mvlan": mvp.Mvlan})
-        var removedStaticChannels []net.IP
-        addedStaticChannels := []net.IP{}
-        /* Taking mvpLock to protect the mvp groups and proxy */
-        mvp.mvpLock.RLock()
-        defer mvp.mvpLock.RUnlock()
+	logger.Infow(ctx, "Update Mvlan Profile task triggered", log.Fields{"Mvlan": mvp.Mvlan})
+	var removedStaticChannels []net.IP
+	addedStaticChannels := []net.IP{}
+	/* Taking mvpLock to protect the mvp groups and proxy */
+	mvp.mvpLock.RLock()
+	defer mvp.mvpLock.RUnlock()
 
-        serialNo := ""
-        if deviceID != "" {
-                if vd := GetApplication().GetDevice(deviceID); vd != nil {
-                        serialNo = vd.SerialNum
-                        if mvp.DevicesList[serialNo] != UpdateInProgress {
-                                logger.Warnw(ctx, "Exiting Update Task since device not present in MvlanProfile", log.Fields{"Device": deviceID, "SerialNum": vd.SerialNum, "MvlanProfile": mvp})
-                                return
-                        }
-                } else {
-                        logger.Errorw(ctx, "Volt Device not found. Stopping Update Mvlan Profile processing for device", log.Fields{"SerialNo": deviceID, "MvlanProfile": mvp})
-                        return
-                }
-        }
+	serialNo := ""
+	if deviceID != "" {
+		if vd := GetApplication().GetDevice(deviceID); vd != nil {
+			serialNo = vd.SerialNum
+			if mvp.DevicesList[serialNo] != UpdateInProgress {
+				logger.Warnw(ctx, "Exiting Update Task since device not present in MvlanProfile", log.Fields{"Device": deviceID, "SerialNum": vd.SerialNum, "MvlanProfile": mvp})
+				return
+			}
+		} else {
+			logger.Errorw(ctx, "Volt Device not found. Stopping Update Mvlan Profile processing for device", log.Fields{"SerialNo": deviceID, "MvlanProfile": mvp})
+			return
+		}
+	}
 
-        //Update the groups based on static channels added & removed
-        if mvp.containsStaticChannels() {
-                addedStaticChannels, removedStaticChannels, _ = mvp.getStaticChannelDiff()
-                logger.Debugw(ctx, "Update Task - Static Group Changes", log.Fields{"Added": addedStaticChannels, "Removed": removedStaticChannels})
+	// Update the groups based on static channels added & removed
+	if mvp.containsStaticChannels() {
+		addedStaticChannels, removedStaticChannels, _ = mvp.getStaticChannelDiff()
+		logger.Debugw(ctx, "Update Task - Static Group Changes", log.Fields{"Added": addedStaticChannels, "Removed": removedStaticChannels})
 
-                if len(addedStaticChannels) > 0 || len(removedStaticChannels) > 0 {
-                        mvp.updateStaticGroups(cntx, deviceID, []net.IP{}, removedStaticChannels)
-                }
-        }
-        mvp.GroupsUpdated(cntx, deviceID)
-        if len(addedStaticChannels) > 0 {
-                mvp.updateStaticGroups(cntx, deviceID, addedStaticChannels, []net.IP{})
-        }
+		if len(addedStaticChannels) > 0 || len(removedStaticChannels) > 0 {
+			mvp.updateStaticGroups(cntx, deviceID, []net.IP{}, removedStaticChannels)
+		}
+	}
+	mvp.GroupsUpdated(cntx, deviceID)
+	if len(addedStaticChannels) > 0 {
+		mvp.updateStaticGroups(cntx, deviceID, addedStaticChannels, []net.IP{})
+	}
 
-        /* Need to handle if SSM params are modified for groups */
-        for key := range mvp.Groups {
-                _, _, commonChannels := mvp.getGroupChannelDiff(mvp.Groups[key], mvp.oldGroups[key])
-                if mvp.checkStaticGrpSSMProxyDiff(mvp.oldProxy[key], mvp.Proxy[key]) {
-                        if mvp.Groups[key].IsStatic {
-                                /* Static group proxy modified, need to trigger membership report with new mode/src-list for existing channels */
-                                mvp.updateStaticGroups(cntx, deviceID, commonChannels, []net.IP{})
-                        } else {
-                                /* Dynamic group proxy modified, need to trigger membership report with new mode/src-list for existing channels */
-                                mvp.updateDynamicGroups(cntx, deviceID, commonChannels, []net.IP{})
-                        }
-                }
-        }
+	/* Need to handle if SSM params are modified for groups */
+	for key := range mvp.Groups {
+		_, _, commonChannels := mvp.getGroupChannelDiff(mvp.Groups[key], mvp.oldGroups[key])
+		if mvp.checkStaticGrpSSMProxyDiff(mvp.oldProxy[key], mvp.Proxy[key]) {
+			if mvp.Groups[key].IsStatic {
+				/* Static group proxy modified, need to trigger membership report with new mode/src-list for existing channels */
+				mvp.updateStaticGroups(cntx, deviceID, commonChannels, []net.IP{})
+			} else {
+				/* Dynamic group proxy modified, need to trigger membership report with new mode/src-list for existing channels */
+				mvp.updateDynamicGroups(cntx, deviceID, commonChannels, []net.IP{})
+			}
+		}
+	}
 
-        mvp.SetUpdateStatus(serialNo, NoOp)
+	mvp.SetUpdateStatus(serialNo, NoOp)
 
-        if deviceID == "" || !mvp.isUpdateInProgress() {
-                mvp.oldGroups = nil
-        }
-        if err := mvp.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
-        }
-        logger.Debugw(ctx, "Updated MVLAN Profile", log.Fields{"VLAN": mvp.Mvlan, "Name": mvp.Name, "Grp IPs": mvp.Groups})
+	if deviceID == "" || !mvp.isUpdateInProgress() {
+		mvp.oldGroups = nil
+	}
+	if err := mvp.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
+	}
+	logger.Debugw(ctx, "Updated MVLAN Profile", log.Fields{"VLAN": mvp.Mvlan, "Name": mvp.Name, "Grp IPs": mvp.Groups})
 }
 
-//checkStaticGrpSSMProxyDiff- return true if the proxy of oldGroup is modified in newGroup
+// checkStaticGrpSSMProxyDiff- return true if the proxy of oldGroup is modified in newGroup
 func (mvp *MvlanProfile) checkStaticGrpSSMProxyDiff(oldProxy *MCGroupProxy, newProxy *MCGroupProxy) bool {
+	if oldProxy == nil && newProxy == nil {
+		return false
+	}
+	if (oldProxy == nil && newProxy != nil) ||
+		(oldProxy != nil && newProxy == nil) {
+		return true
+	}
 
-        if oldProxy == nil && newProxy == nil {
-                return false
-        }
-        if (oldProxy == nil && newProxy != nil) ||
-                (oldProxy != nil && newProxy == nil) {
-                return true
-        }
+	if oldProxy.Mode != newProxy.Mode {
+		return true
+	}
 
-        if oldProxy.Mode != newProxy.Mode {
-                return true
-        }
+	oldSrcLst := oldProxy.SourceList
+	newSrcLst := newProxy.SourceList
+	oLen := len(oldSrcLst)
+	nLen := len(newSrcLst)
+	if oLen != nLen {
+		return true
+	}
 
-        oldSrcLst := oldProxy.SourceList
-        newSrcLst := newProxy.SourceList
-        oLen := len(oldSrcLst)
-        nLen := len(newSrcLst)
-        if oLen != nLen {
-                return true
-        }
+	visited := make([]bool, nLen)
 
-        visited := make([]bool, nLen)
+	/* check if any new IPs added in the src list, return true if present */
+	for i := 0; i < nLen; i++ {
+		found := false
+		element := newSrcLst[i]
+		for j := 0; j < oLen; j++ {
+			if visited[j] {
+				continue
+			}
+			if element.Equal(oldSrcLst[j]) {
+				visited[j] = true
+				found = true
+				break
+			}
+		}
+		if !found {
+			return true
+		}
+	}
 
-        /* check if any new IPs added in the src list, return true if present */
-        for i := 0; i < nLen; i++ {
-                found := false
-                element := newSrcLst[i]
-                for j := 0; j < oLen; j++ {
-                        if visited[j] {
-                                continue
-                        }
-                        if element.Equal(oldSrcLst[j]) {
-                                visited[j] = true
-                                found = true
-                                break
-                        }
-                }
-                if !found {
-                        return true
-                }
-        }
-
-        visited = make([]bool, nLen)
-        /* check if any IPs removed from existing  src list, return true if removed */
-        for i := 0; i < oLen; i++ {
-                found := false
-                element := oldSrcLst[i]
-                for j := 0; j < nLen; j++ {
-                        if visited[j] {
-                                continue
-                        }
-                        if element.Equal(newSrcLst[j]) {
-                                visited[j] = true
-                                found = true
-                                break
-                        }
-                }
-                if !found {
-                        return true
-                }
-        }
-        return false
+	visited = make([]bool, nLen)
+	/* check if any IPs removed from existing  src list, return true if removed */
+	for i := 0; i < oLen; i++ {
+		found := false
+		element := oldSrcLst[i]
+		for j := 0; j < nLen; j++ {
+			if visited[j] {
+				continue
+			}
+			if element.Equal(newSrcLst[j]) {
+				visited[j] = true
+				found = true
+				break
+			}
+		}
+		if !found {
+			return true
+		}
+	}
+	return false
 }
 
-
-//UpdateActiveChannelSubscriberAlarm - Updates the Active Channel Subscriber Alarm
+// UpdateActiveChannelSubscriberAlarm - Updates the Active Channel Subscriber Alarm
 func (mvp *MvlanProfile) UpdateActiveChannelSubscriberAlarm() {
-        va := GetApplication()
-        logger.Debugw(ctx, "Update of Active Channel Subscriber Alarm", log.Fields{"Mvlan": mvp.Mvlan})
-        for srNo := range mvp.DevicesList {
-                d, _ := va.GetDeviceBySerialNo(srNo)
-                if d == nil {
-                        logger.Warnw(ctx, "Device info not found", log.Fields{"Device_SrNo": srNo, "Mvlan": mvp.Mvlan})
-                        return
-                }
-                d.Ports.Range(func(key, value interface{}) bool {
-                        //port := key.(string)
-                        vp := value.(*VoltPort)
-                        if vp.Type != VoltPortTypeAccess {
-                                return true
-                        }
-                        if mvp.MaxActiveChannels > vp.ActiveChannels && vp.ChannelPerSubAlarmRaised {
-                                serviceName := GetMcastServiceForSubAlarm(vp, mvp)
-                                logger.Debugw(ctx, "Clearing-SendActiveChannelPerSubscriberAlarm-due-to-update", log.Fields{"ActiveChannels": vp.ActiveChannels, "ServiceName": serviceName})
-                                vp.ChannelPerSubAlarmRaised = false
-                        } else if mvp.MaxActiveChannels < vp.ActiveChannels && !vp.ChannelPerSubAlarmRaised {
-                                /* When the max active channel count is reduced via update, we raise an alarm.
-                                   But the previous excess channels still exist until a leave or expiry */
-                                serviceName := GetMcastServiceForSubAlarm(vp, mvp)
-                                logger.Debugw(ctx, "Raising-SendActiveChannelPerSubscriberAlarm-due-to-update", log.Fields{"ActiveChannels": vp.ActiveChannels, "ServiceName": serviceName})
-                                vp.ChannelPerSubAlarmRaised = true
-                        }
-                        return true
-                })
-        }
+	va := GetApplication()
+	logger.Debugw(ctx, "Update of Active Channel Subscriber Alarm", log.Fields{"Mvlan": mvp.Mvlan})
+	for srNo := range mvp.DevicesList {
+		d, _ := va.GetDeviceBySerialNo(srNo)
+		if d == nil {
+			logger.Warnw(ctx, "Device info not found", log.Fields{"Device_SrNo": srNo, "Mvlan": mvp.Mvlan})
+			return
+		}
+		d.Ports.Range(func(key, value interface{}) bool {
+			//port := key.(string)
+			vp := value.(*VoltPort)
+			if vp.Type != VoltPortTypeAccess {
+				return true
+			}
+			if mvp.MaxActiveChannels > vp.ActiveChannels && vp.ChannelPerSubAlarmRaised {
+				serviceName := GetMcastServiceForSubAlarm(vp, mvp)
+				logger.Debugw(ctx, "Clearing-SendActiveChannelPerSubscriberAlarm-due-to-update", log.Fields{"ActiveChannels": vp.ActiveChannels, "ServiceName": serviceName})
+				vp.ChannelPerSubAlarmRaised = false
+			} else if mvp.MaxActiveChannels < vp.ActiveChannels && !vp.ChannelPerSubAlarmRaised {
+				/* When the max active channel count is reduced via update, we raise an alarm.
+				   But the previous excess channels still exist until a leave or expiry */
+				serviceName := GetMcastServiceForSubAlarm(vp, mvp)
+				logger.Debugw(ctx, "Raising-SendActiveChannelPerSubscriberAlarm-due-to-update", log.Fields{"ActiveChannels": vp.ActiveChannels, "ServiceName": serviceName})
+				vp.ChannelPerSubAlarmRaised = true
+			}
+			return true
+		})
+	}
 }
 
-//TriggerAssociatedFlowDelete - Re-trigger delete for pending delete flows
+// TriggerAssociatedFlowDelete - Re-trigger delete for pending delete flows
 func (mvp *MvlanProfile) TriggerAssociatedFlowDelete(cntx context.Context, device string) bool {
-        mvp.mvpFlowLock.Lock()
+	mvp.mvpFlowLock.Lock()
 
-        cookieList := []uint64{}
-        flowMap := mvp.PendingDeleteFlow[device]
+	cookieList := []uint64{}
+	flowMap := mvp.PendingDeleteFlow[device]
 
-        for cookie := range flowMap {
-                cookieList = append(cookieList, convertToUInt64(cookie))
-        }
-        mvp.mvpFlowLock.Unlock()
+	for cookie := range flowMap {
+		cookieList = append(cookieList, convertToUInt64(cookie))
+	}
+	mvp.mvpFlowLock.Unlock()
 
-        if len(cookieList) == 0 {
-                return false
-        }
+	if len(cookieList) == 0 {
+		return false
+	}
 
-        for _, cookie := range cookieList {
-                if vd := GetApplication().GetDevice(device); vd != nil {
-                        flow := &of.VoltFlow{}
-                        flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
-                        subFlow := of.NewVoltSubFlow()
-                        subFlow.Cookie = cookie
-                        flow.SubFlows[cookie] = subFlow
-                        logger.Infow(ctx, "Retriggering Vnet Delete Flow", log.Fields{"Device": device, "Mvlan": mvp.Mvlan.String(), "Cookie": cookie})
-                        err := mvp.DelFlows(cntx, vd, flow)
-                        if err != nil {
-                                logger.Warnw(ctx, "De-Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
-                        }
-                }
-        }
-        return true
+	for _, cookie := range cookieList {
+		if vd := GetApplication().GetDevice(device); vd != nil {
+			flow := &of.VoltFlow{}
+			flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
+			subFlow := of.NewVoltSubFlow()
+			subFlow.Cookie = cookie
+			flow.SubFlows[cookie] = subFlow
+			logger.Infow(ctx, "Retriggering Vnet Delete Flow", log.Fields{"Device": device, "Mvlan": mvp.Mvlan.String(), "Cookie": cookie})
+			err := mvp.DelFlows(cntx, vd, flow)
+			if err != nil {
+				logger.Warnw(ctx, "De-Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
+			}
+		}
+	}
+	return true
 }
 
-// JsonMarshal wrapper function for json Marshal MvlanProfile
-func (mvp *MvlanProfile) JsonMarshal() ([]byte, error) {
-        return json.Marshal(MvlanProfile{
-                Name:                mvp.Name,
-                Mvlan:               mvp.Mvlan,
-                PonVlan:             mvp.PonVlan,
-                Groups:              mvp.Groups,
-                Proxy:               mvp.Proxy,
-                Version:             mvp.Version,
-                IsPonVlanPresent:    mvp.IsPonVlanPresent,
-                IsChannelBasedGroup: mvp.IsChannelBasedGroup,
-                DevicesList:         mvp.DevicesList,
-                MaxActiveChannels:   mvp.MaxActiveChannels,
-                PendingDeleteFlow:   mvp.PendingDeleteFlow,
-                DeleteInProgress:    mvp.DeleteInProgress,
-                IgmpServVersion:     mvp.IgmpServVersion,
-        })
+// JSONMarshal wrapper function for json Marshal MvlanProfile
+func (mvp *MvlanProfile) JSONMarshal() ([]byte, error) {
+	return json.Marshal(MvlanProfile{
+		Name:                mvp.Name,
+		Mvlan:               mvp.Mvlan,
+		PonVlan:             mvp.PonVlan,
+		Groups:              mvp.Groups,
+		Proxy:               mvp.Proxy,
+		Version:             mvp.Version,
+		IsPonVlanPresent:    mvp.IsPonVlanPresent,
+		IsChannelBasedGroup: mvp.IsChannelBasedGroup,
+		DevicesList:         mvp.DevicesList,
+		MaxActiveChannels:   mvp.MaxActiveChannels,
+		PendingDeleteFlow:   mvp.PendingDeleteFlow,
+		DeleteInProgress:    mvp.DeleteInProgress,
+		IgmpServVersion:     mvp.IgmpServVersion,
+	})
 }
 
 // removeIPFromList to remove ip from the list
 func removeIPFromList(s []net.IP, value net.IP) []net.IP {
-        i := 0
-        for i = 0; i < len(s); i++ {
-                if s[i].Equal(value) {
-                        break
-                }
-        }
-        if i != len(s) {
-                //It means value is found in the slice
-                return append(s[0:i], s[i+1:]...)
-        }
-        return s
+	i := 0
+	for i = 0; i < len(s); i++ {
+		if s[i].Equal(value) {
+			break
+		}
+	}
+	if i != len(s) {
+		//It means value is found in the slice
+		return append(s[0:i], s[i+1:]...)
+	}
+	return s
 }
 
 // doesIPMatch to check if ip match with any ip from the list
 func doesIPMatch(ip net.IP, ipsOrRange []string) bool {
-        for _, ipOrRange := range ipsOrRange {
-                if strings.Contains(ipOrRange, "-") {
-                        var splits = strings.Split(ipOrRange, "-")
-                        ipStart := util.IP2LongConv(net.ParseIP(splits[0]))
-                        ipEnd := util.IP2LongConv(net.ParseIP(splits[1]))
-                        if ipEnd < ipStart {
-                                return false
-                        }
-                        ipInt := util.IP2LongConv(ip)
-                        if ipInt >= ipStart && ipInt <= ipEnd {
-                                return true
-                        }
-                } else if ip.Equal(net.ParseIP(ipOrRange)) {
-                        return true
-                }
-        }
-        return false
+	for _, ipOrRange := range ipsOrRange {
+		if strings.Contains(ipOrRange, "-") {
+			var splits = strings.Split(ipOrRange, "-")
+			ipStart := util.IP2LongConv(net.ParseIP(splits[0]))
+			ipEnd := util.IP2LongConv(net.ParseIP(splits[1]))
+			if ipEnd < ipStart {
+				return false
+			}
+			ipInt := util.IP2LongConv(ip)
+			if ipInt >= ipStart && ipInt <= ipEnd {
+				return true
+			}
+		} else if ip.Equal(net.ParseIP(ipOrRange)) {
+			return true
+		}
+	}
+	return false
 }
 
 // IgmpProfile structure
 type IgmpProfile struct {
-        ProfileID          string
-        UnsolicitedTimeOut uint32 //In seconds
-        MaxResp            uint32
-        KeepAliveInterval  uint32
-        KeepAliveCount     uint32
-        LastQueryInterval  uint32
-        LastQueryCount     uint32
-        FastLeave          bool
-        PeriodicQuery      bool
-        IgmpCos            uint8
-        WithRAUpLink       bool
-        WithRADownLink     bool
-        IgmpVerToServer    string
-        IgmpSourceIP       net.IP
-        Version            string
+	ProfileID          string
+	IgmpVerToServer    string
+	Version            string
+	IgmpSourceIP       net.IP
+	UnsolicitedTimeOut uint32 //In seconds
+	MaxResp            uint32
+	KeepAliveInterval  uint32
+	KeepAliveCount     uint32
+	LastQueryInterval  uint32
+	LastQueryCount     uint32
+	IgmpCos            uint8
+	FastLeave          bool
+	PeriodicQuery      bool
+	WithRAUpLink       bool
+	WithRADownLink     bool
 }
 
 func newIgmpProfile(igmpProfileConfig *common.IGMPConfig) *IgmpProfile {
-        var igmpProfile IgmpProfile
-        igmpProfile.ProfileID = igmpProfileConfig.ProfileID
-        igmpProfile.UnsolicitedTimeOut = uint32(igmpProfileConfig.UnsolicitedTimeOut)
-        igmpProfile.MaxResp = uint32(igmpProfileConfig.MaxResp)
+	var igmpProfile IgmpProfile
+	igmpProfile.ProfileID = igmpProfileConfig.ProfileID
+	igmpProfile.UnsolicitedTimeOut = uint32(igmpProfileConfig.UnsolicitedTimeOut)
+	igmpProfile.MaxResp = uint32(igmpProfileConfig.MaxResp)
 
-        keepAliveInterval := uint32(igmpProfileConfig.KeepAliveInterval)
+	keepAliveInterval := uint32(igmpProfileConfig.KeepAliveInterval)
 
-        //KeepAliveInterval should have a min of 10 seconds
-        if keepAliveInterval < MinKeepAliveInterval {
-                keepAliveInterval = MinKeepAliveInterval
-                logger.Infow(ctx, "Auto adjust keepAliveInterval - Value < 10", log.Fields{"Received": igmpProfileConfig.KeepAliveInterval, "Configured": keepAliveInterval})
-        }
-        igmpProfile.KeepAliveInterval = keepAliveInterval
+	//KeepAliveInterval should have a min of 10 seconds
+	if keepAliveInterval < MinKeepAliveInterval {
+		keepAliveInterval = MinKeepAliveInterval
+		logger.Infow(ctx, "Auto adjust keepAliveInterval - Value < 10", log.Fields{"Received": igmpProfileConfig.KeepAliveInterval, "Configured": keepAliveInterval})
+	}
+	igmpProfile.KeepAliveInterval = keepAliveInterval
 
-        igmpProfile.KeepAliveCount = uint32(igmpProfileConfig.KeepAliveCount)
-        igmpProfile.LastQueryInterval = uint32(igmpProfileConfig.LastQueryInterval)
-        igmpProfile.LastQueryCount = uint32(igmpProfileConfig.LastQueryCount)
-        igmpProfile.FastLeave = *igmpProfileConfig.FastLeave
-        igmpProfile.PeriodicQuery = *igmpProfileConfig.PeriodicQuery
-        igmpProfile.IgmpCos = uint8(igmpProfileConfig.IgmpCos)
-        igmpProfile.WithRAUpLink = *igmpProfileConfig.WithRAUpLink
-        igmpProfile.WithRADownLink = *igmpProfileConfig.WithRADownLink
+	igmpProfile.KeepAliveCount = uint32(igmpProfileConfig.KeepAliveCount)
+	igmpProfile.LastQueryInterval = uint32(igmpProfileConfig.LastQueryInterval)
+	igmpProfile.LastQueryCount = uint32(igmpProfileConfig.LastQueryCount)
+	igmpProfile.FastLeave = *igmpProfileConfig.FastLeave
+	igmpProfile.PeriodicQuery = *igmpProfileConfig.PeriodicQuery
+	igmpProfile.IgmpCos = uint8(igmpProfileConfig.IgmpCos)
+	igmpProfile.WithRAUpLink = *igmpProfileConfig.WithRAUpLink
+	igmpProfile.WithRADownLink = *igmpProfileConfig.WithRADownLink
 
-        if igmpProfileConfig.IgmpVerToServer == "2" || igmpProfileConfig.IgmpVerToServer == "v2" {
-                igmpProfile.IgmpVerToServer = "2"
-        } else {
-                igmpProfile.IgmpVerToServer = "3"
-        }
-        igmpProfile.IgmpSourceIP = net.ParseIP(igmpProfileConfig.IgmpSourceIP)
+	if igmpProfileConfig.IgmpVerToServer == "2" || igmpProfileConfig.IgmpVerToServer == "v2" {
+		igmpProfile.IgmpVerToServer = "2"
+	} else {
+		igmpProfile.IgmpVerToServer = "3"
+	}
+	igmpProfile.IgmpSourceIP = net.ParseIP(igmpProfileConfig.IgmpSourceIP)
 
-        return &igmpProfile
+	return &igmpProfile
 }
 
 // newDefaultIgmpProfile Igmp profiles with default values
 func newDefaultIgmpProfile() *IgmpProfile {
-        return &IgmpProfile{
-                ProfileID:          DefaultIgmpProfID,
-                UnsolicitedTimeOut: 60,
-                MaxResp:            10, // seconds
-                KeepAliveInterval:  60, // seconds
-                KeepAliveCount:     3,  // TODO - May not be needed
-                LastQueryInterval:  0,  // TODO - May not be needed
-                LastQueryCount:     0,  // TODO - May not be needed
-                FastLeave:          true,
-                PeriodicQuery:      false, // TODO - May not be needed
-                IgmpCos:            7,     //p-bit value included in the IGMP packet
-                WithRAUpLink:       false, // TODO - May not be needed
-                WithRADownLink:     false, // TODO - May not be needed
-                IgmpVerToServer:    "3",
-                IgmpSourceIP:       net.ParseIP("172.27.0.1"), // This will be replaced by configuration
-        }
+	return &IgmpProfile{
+		ProfileID:          DefaultIgmpProfID,
+		UnsolicitedTimeOut: 60,
+		MaxResp:            10, // seconds
+		KeepAliveInterval:  60, // seconds
+		KeepAliveCount:     3,  // TODO - May not be needed
+		LastQueryInterval:  0,  // TODO - May not be needed
+		LastQueryCount:     0,  // TODO - May not be needed
+		FastLeave:          true,
+		PeriodicQuery:      false, // TODO - May not be needed
+		IgmpCos:            7,     //p-bit value included in the IGMP packet
+		WithRAUpLink:       false, // TODO - May not be needed
+		WithRADownLink:     false, // TODO - May not be needed
+		IgmpVerToServer:    "3",
+		IgmpSourceIP:       net.ParseIP("172.27.0.1"), // This will be replaced by configuration
+	}
 }
 
 // WriteToDb is utility to write Igmp Config Info to database
 func (igmpProfile *IgmpProfile) WriteToDb(cntx context.Context) error {
-        igmpProfile.Version = database.PresentVersionMap[database.IgmpProfPath]
-        b, err := json.Marshal(igmpProfile)
-        if err != nil {
-                return err
-        }
-        if err1 := db.PutIgmpProfile(cntx, igmpProfile.ProfileID, string(b)); err1 != nil {
-                return err1
-        }
-        return nil
+	igmpProfile.Version = database.PresentVersionMap[database.IgmpProfPath]
+	b, err := json.Marshal(igmpProfile)
+	if err != nil {
+		return err
+	}
+	if err1 := db.PutIgmpProfile(cntx, igmpProfile.ProfileID, string(b)); err1 != nil {
+		return err1
+	}
+	return nil
 }
diff --git a/internal/pkg/application/igmptasks.go b/internal/pkg/application/igmptasks.go
index 268453c..c56d374 100644
--- a/internal/pkg/application/igmptasks.go
+++ b/internal/pkg/application/igmptasks.go
@@ -40,8 +40,8 @@
 // TickTask structure
 type TickTask struct {
 	ctx    context.Context
-	taskID uint8
 	ts     string
+	taskID uint8
 }
 
 // NewTickTask is constructor for TickTask
@@ -84,11 +84,11 @@
 // IgmpPacketTask structure
 type IgmpPacketTask struct {
 	ctx    context.Context
-	taskID uint8
+	Pkt    gopacket.Packet
 	Device string
 	Port   string
-	Pkt    gopacket.Packet
 	ts     string
+	taskID uint8
 }
 
 // NewIgmpPacketTask is the constructor for IgmpPacketTask
@@ -131,10 +131,10 @@
 // UpdateMvlanTask structure
 type UpdateMvlanTask struct {
 	ctx      context.Context
-	taskID   uint8
-	DeviceID string
 	mvp      *MvlanProfile
+	DeviceID string
 	ts       string
+	taskID   uint8
 }
 
 // NewUpdateMvlanTask is the constructor for UpdateMvlanTask
diff --git a/internal/pkg/application/major_upgrade.go b/internal/pkg/application/major_upgrade.go
index b423b58..2cd488c 100644
--- a/internal/pkg/application/major_upgrade.go
+++ b/internal/pkg/application/major_upgrade.go
@@ -19,8 +19,8 @@
 	"context"
 	"encoding/json"
 	"errors"
-	"voltha-go-controller/internal/pkg/types"
 	"sync"
+	common "voltha-go-controller/internal/pkg/types"
 
 	"github.com/google/gopacket/layers"
 
@@ -29,28 +29,28 @@
 )
 
 const (
-	//MigrationComplete Represents the Migration Complete
+	// MigrationComplete Represents the Migration Complete
 	MigrationComplete = "Completed"
-	//MigrationInProgress Represents the Migration Inprogress
+	// MigrationInProgress Represents the Migration Inprogress
 	MigrationInProgress = "InProgress"
-	//MigrationFailed  Represents the Migration Failed
+	// MigrationFailed  Represents the Migration Failed
 	MigrationFailed = "Failed"
 	// StatusNone for no operations
 	StatusNone = "NONE"
-	//ModuleToBeDeleted - module where old version is deleted
+	// ModuleToBeDeleted - module where old version is deleted
 	ModuleToBeDeleted = "ModuleToBeDeleted"
 )
 
-//DataMigration represents the Verison and Status info for Major Version Upgrade.
+// DataMigration represents the Version and Status info for Major Version Upgrade.
 type DataMigration struct {
+	ModuleVer map[string]string // eg. "service": "v1"
 	Version   string
 	Status    string
-	ModuleVer map[string]string // eg. "service": "v1"
 }
 
 type paramsMigrationFunc func(context.Context, []byte) string
 
-//map to store conversion functions
+// map to store conversion functions
 var migrationMap = map[string]paramsMigrationFunc{
 	database.ServicePath:        MigrateServices,
 	database.DevicePath:         MigrateDevices,
@@ -124,12 +124,12 @@
 	var NoDataInDB bool
 	err := GetMigrationInfo(ctx, Migrate)
 	logger.Debugw(ctx, "Migration data", log.Fields{"DataMigration": Migrate})
-	// No DB entry represents N verison Bring Up for the First time
+	// No DB entry represents N version Bring Up for the First time
 	if err != nil {
 		NoDataInDB = true
 		logger.Error(ctx, "Failed to read the Migration Data from DB ")
 	}
-	// Covers N verison bringup and Reboot Senarios
+	// Covers N version bringup and Reboot Scenarios
 	if NoDataInDB {
 		logger.Info(ctx, "Data Migration Not Required")
 		Migrate.Version = database.PresentVersion
@@ -138,9 +138,9 @@
 		if err := Migrate.WriteToDb(ctx); err != nil {
 			logger.Errorw(ctx, "DB Write failed for Migration Path", log.Fields{"error": err})
 		}
-		//MigrateProbestatus has to be Updated to Complete when No Migration is Required
+		// MigrateProbestatus has to be Updated to Complete when No Migration is Required
 		logger.Debugw(ctx, "Migration Probe Status", log.Fields{"Migration Probe": Migrate.Status})
-		//probe.UpdateDBMigrationStatus(ctx, true)
+		// probe.UpdateDBMigrationStatus(ctx, true)
 		return false
 		// Migration required when vgc moves to Higher Versions
 	} else if Migrate.ModuleVer == nil {
@@ -185,7 +185,7 @@
 	Migrate := new(DataMigration)
 	var migrationWG sync.WaitGroup
 
-	//Keeping it outside to avoid race condition where the
+	// Keeping it outside to avoid race condition where the
 	// wait check is reached before the go toutine for data migraiton is triggered
 	migrationWG.Add(1)
 
@@ -195,7 +195,7 @@
 		if err != nil {
 			logger.Errorw(ctx, "Failed to Migrate the Data", log.Fields{"error": err})
 			Migrate.Status = MigrationFailed
-			if err := Migrate.WriteToDb(ctx); err != nil {
+			if err = Migrate.WriteToDb(ctx); err != nil {
 				logger.Errorw(ctx, "DB Write failed to Migration Path", log.Fields{"error": err})
 			}
 		}
@@ -213,7 +213,7 @@
 	// Failure Senario can be Exceptions, incase of panic Update the status as failed
 	defer func() {
 		if err := recover(); err != nil {
-			logger.Errorw(ctx, "Migration failure due to Exception happend", log.Fields{"reason": err})
+			logger.Errorw(ctx, "Migration failure due to Exception happened", log.Fields{"reason": err})
 			Migrate.Status = MigrationFailed
 			if err := Migrate.WriteToDb(ctx); err != nil {
 				logger.Errorw(ctx, "DB Write failed for Migration Path", log.Fields{"error": err})
@@ -234,7 +234,6 @@
 
 // MigrateDBData to migrate database data
 func MigrateDBData(cntx context.Context) error {
-
 	var err error
 	for module, currentVersion := range database.PresentVersionMap {
 		if currentVersion == database.DBVersionMap[module] {
@@ -265,20 +264,19 @@
 	return nil
 }
 
-//FetchAndMigrateDeviceDBData fetchs the data from database and migrte the same to latest versions and store ot back ot database
+// FetchAndMigrateDeviceDBData fetchs the data from database and migrte the same to latest versions and store ot back ot database
 func FetchAndMigrateDeviceDBData(module string) error {
 	logger.Error(ctx, "Data Migration not implemented for Device DB Data")
 	return nil
 }
 
-//FetchAndMigrateDBData fetchs the data from database and migrte the same to latest versions and store ot back ot database
+// FetchAndMigrateDBData fetchs the data from database and migrte the same to latest versions and store ot back ot database
 func FetchAndMigrateDBData(cntx context.Context, module string) error {
-
 	previousPath := database.GetModuleKeypath(module, database.PreviousVersionMap[module])
 	dbPathKeysValueMap, err := db.List(cntx, previousPath)
 	if err != nil {
 		logger.Errorw(ctx, "failed to Fetch the Keys from Redis", log.Fields{"error": err})
-		//No return required, Data might not be present in DB
+		// No return required, Data might not be present in DB
 		return nil
 	}
 	if len(dbPathKeysValueMap) == 0 {
@@ -289,7 +287,7 @@
 	// Fetch each Path from previous version and store to present version after data migration changes
 	for hash, value := range dbPathKeysValueMap {
 		logger.Debugw(ctx, "DB path", log.Fields{"hash": hash})
-		//convert the value to a specific type based on the dbPath
+		// convert the value to a specific type based on the dbPath
 		b, ok := value.Value.([]byte)
 		if !ok {
 			logger.Error(ctx, "The value type is not []byte")
@@ -314,7 +312,7 @@
 	return nil
 }
 
-//MigrateServices modifyies the old data as per current version requirement and updates the database
+// MigrateServices modifyies the old data as per current version requirement and updates the database
 func MigrateServices(cntx context.Context, data []byte) string {
 	var vs VoltService
 	var updatedData, updatedData1 []byte
@@ -339,15 +337,14 @@
 
 	if vsmap["MacLearning"] == true {
 		vs.MacLearning = Learn
-
 	}
 
-	//Migration
+	// Migration
 	vs.PendingFlows = make(map[string]bool)
 	vs.AssociatedFlows = make(map[string]bool)
 	vs.DeleteInProgress = false
 	vs.PonPort = 0xFF
-	if updatedData, err = vs.JsonMarshal(); err != nil {
+	if updatedData, err = vs.JSONMarshal(); err != nil {
 		logger.Warnw(ctx, "Marshal of Service failed", log.Fields{"Error": err.Error()})
 		return ""
 	}
@@ -355,45 +352,44 @@
 	return string(updatedData)
 }
 
-//MigrateDevices modifyies the old data as per current version requirement and updates the database
+// MigrateDevices modifyies the old data as per current version requirement and updates the database
 func MigrateDevices(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Devices")
 	return ""
 }
 
-//MigrateDevicePorts modifyies the old data as per current version requirement and updates the database
+// MigrateDevicePorts modifyies the old data as per current version requirement and updates the database
 func MigrateDevicePorts(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Ports")
 	return ""
 }
 
-//MigrateDeviceFlows modifyies the old data as per current version requirement and updates the database
+// MigrateDeviceFlows modifyies the old data as per current version requirement and updates the database
 func MigrateDeviceFlows(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Flows")
 	return ""
 }
 
-//MigrateDeviceGroups modifyies the old data as per current version requirement and updates the database
+// MigrateDeviceGroups modifyies the old data as per current version requirement and updates the database
 func MigrateDeviceGroups(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Groups")
 	return ""
 }
 
-//MigrateDeviceMeters modifyies the old data as per current version requirement and updates the database
+// MigrateDeviceMeters modifyies the old data as per current version requirement and updates the database
 func MigrateDeviceMeters(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Meters")
 	return ""
 }
 
-//MigrateDeviceFlowHash modifyies the old data as per current version requirement and updates the database
+// MigrateDeviceFlowHash modifyies the old data as per current version requirement and updates the database
 func MigrateDeviceFlowHash(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for FlowHash")
 	return ""
 }
 
-//MigrateVnets modifyies the old data as per current version requirement and updates the database
+// MigrateVnets modifyies the old data as per current version requirement and updates the database
 func MigrateVnets(cntx context.Context, data []byte) string {
-
 	var vnet VoltVnet
 	var updatedData []byte
 
@@ -414,7 +410,7 @@
 	}
 	vnet.PendingDeleteFlow = make(map[string]map[string]bool)
 	vnet.DeleteInProgress = false
-	if updatedData, err = vnet.JsonMarshal(); err != nil {
+	if updatedData, err = vnet.JSONMarshal(); err != nil {
 		logger.Warnw(ctx, "Marshal of Vnet failed", log.Fields{"Error": err.Error()})
 		return ""
 	}
@@ -422,7 +418,7 @@
 	return string(updatedData)
 }
 
-//MigrateVpvs modifyies the old data as per current version requirement and updates the database
+// MigrateVpvs modifyies the old data as per current version requirement and updates the database
 func MigrateVpvs(cntx context.Context, data []byte) string {
 	var vpv VoltPortVnet
 	var updatedData, updatedData1 []byte
@@ -443,12 +439,10 @@
 
 	if err2 := json.Unmarshal(updatedData1, &vpv); err != nil {
 		logger.Warnw(ctx, "Unmarshal-failed", log.Fields{"err": err2})
-
 	}
 
 	if vpvmap["MacLearning"] == true {
 		vpv.MacLearning = Learn
-
 	}
 	if vpvmap["UsFlowsApplied"] == true {
 		usFlowsApplied = true
@@ -461,7 +455,7 @@
 	if usFlowsApplied && dsFlowsApplied {
 		vpv.FlowsApplied = true
 	}
-	//Migration
+	// Migration
 	if vpv.SVlanTpid == 0 {
 		vpv.SVlanTpid = layers.EthernetTypeDot1Q
 	}
@@ -469,16 +463,16 @@
 	vpv.PendingDeleteFlow = make(map[string]bool)
 	vpv.PonPort = 0xFF
 
-	if updatedData, err = vpv.JsonMarshal(); err != nil {
+	if updatedData, err = vpv.JSONMarshal(); err != nil {
 		logger.Warnw(ctx, "Marshal of VPV failed", log.Fields{"Error": err.Error()})
 		return ""
 	}
 	logger.Infow(ctx, "VPV Migrated", log.Fields{"Device": vpv.Device, "port": vpv.Port, "SVlan": vpv.SVlan,
-			"CVlan": vpv.CVlan, "UniVlan": vpv.UniVlan, "PresentVersion": database.PresentVersionMap[database.VpvPath]})
+		"CVlan": vpv.CVlan, "UniVlan": vpv.UniVlan, "PresentVersion": database.PresentVersionMap[database.VpvPath]})
 	return string(updatedData)
 }
 
-//MigrateMvlans modifyies the old data as per current version requirement and updates the database
+// MigrateMvlans modifyies the old data as per current version requirement and updates the database
 func MigrateMvlans(cntx context.Context, data []byte) string {
 	var mvp MvlanProfile
 	var updatedData []byte
@@ -495,7 +489,7 @@
 		mvp.IgmpServVersion[srNo] = &servVersion
 	}
 
-	if updatedData, err = mvp.JsonMarshal(); err != nil {
+	if updatedData, err = mvp.JSONMarshal(); err != nil {
 		logger.Warnw(ctx, "Marshal of Mvlan Profile failed", log.Fields{"Error": err.Error()})
 		return ""
 	}
@@ -503,13 +497,13 @@
 	return string(updatedData)
 }
 
-//MigrateMeters modifyies the old data as per current version requirement and updates the database
+// MigrateMeters modifyies the old data as per current version requirement and updates the database
 func MigrateMeters(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Meters")
 	return ""
 }
 
-//MigrateIgmpConfs modifyies the old data as per current version requirement and updates the database
+// MigrateIgmpConfs modifyies the old data as per current version requirement and updates the database
 func MigrateIgmpConfs(cntx context.Context, data []byte) string {
 	var igmpProfile IgmpProfile
 
@@ -526,85 +520,85 @@
 	return ModuleToBeDeleted
 }
 
-//MigrateIgmpGroups modifyies the old data as per current version requirement and updates the database
+// MigrateIgmpGroups modifyies the old data as per current version requirement and updates the database
 func MigrateIgmpGroups(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for IGMP Groups")
 	return ""
 }
 
-//MigrateIgmpDevices modifyies the old data as per current version requirement and updates the database
+// MigrateIgmpDevices modifyies the old data as per current version requirement and updates the database
 func MigrateIgmpDevices(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for IGMP Device")
 	return ""
 }
 
-//MigrateIgmpChannels modifyies the old data as per current version requirement and updates the database
+// MigrateIgmpChannels modifyies the old data as per current version requirement and updates the database
 func MigrateIgmpChannels(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for IGMP Channels")
 	return ""
 }
 
-//MigrateIgmpPorts modifyies the old data as per current version requirement and updates the database
+// MigrateIgmpPorts modifyies the old data as per current version requirement and updates the database
 func MigrateIgmpPorts(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for IGMP Ports")
 	return ""
 }
 
-//MigrateIgmpProfs modifyies the old data as per current version requirement and updates the database
+// MigrateIgmpProfs modifyies the old data as per current version requirement and updates the database
 func MigrateIgmpProfs(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for IGMP Profs")
 	return ""
 }
 
-//MigrateMcastConfs modifyies the old data as per current version requirement and updates the database
+// MigrateMcastConfs modifyies the old data as per current version requirement and updates the database
 func MigrateMcastConfs(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Mcast Confs")
 	return ""
 }
 
-//MigrateLogLevels modifyies the old data as per current version requirement and updates the database
+// MigrateLogLevels modifyies the old data as per current version requirement and updates the database
 func MigrateLogLevels(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Log Levels")
 	return ""
 }
 
-//MigrateHealth modifyies the old data as per current version requirement and updates the database
+// MigrateHealth modifyies the old data as per current version requirement and updates the database
 func MigrateHealth(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Health")
 	return ""
 }
 
-//MigratePonCounters modifyies the old data as per current version requirement and updates the database
+// MigratePonCounters modifyies the old data as per current version requirement and updates the database
 func MigratePonCounters(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Pon Counters")
 	return ""
 }
 
-//MigrateChannelCounters modifyies the old data as per current version requirement and updates the database
+// MigrateChannelCounters modifyies the old data as per current version requirement and updates the database
 func MigrateChannelCounters(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Channel Counters")
 	return ""
 }
 
-//MigrateServiceCounters modifyies the old data as per current version requirement and updates the database
+// MigrateServiceCounters modifyies the old data as per current version requirement and updates the database
 func MigrateServiceCounters(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for Service Counters")
 	return ""
 }
 
-//MigrateNbDevices modifyies the old data as per current version requirement and updates the database
+// MigrateNbDevices modifyies the old data as per current version requirement and updates the database
 func MigrateNbDevices(cntx context.Context, data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for NB Devices")
 	return ""
 }
 
-//MigrateFlowHash modifyies the old data as per current version requirement and updates the database
+// MigrateFlowHash modifyies the old data as per current version requirement and updates the database
 func MigrateFlowHash(data []byte) string {
 	logger.Error(ctx, "Data Migration not implemented for FLow Hash")
 	return ""
 }
 
-//DeleteDbPathKeys Deleted the paths from DB
+// DeleteDbPathKeys Deleted the paths from DB
 func DeleteDbPathKeys(cntx context.Context, keyPath string) error {
 	logger.Debugw(ctx, "Deleting paths for version", log.Fields{"Path": keyPath})
 
diff --git a/internal/pkg/application/meters.go b/internal/pkg/application/meters.go
index 276fe99..2592be5 100644
--- a/internal/pkg/application/meters.go
+++ b/internal/pkg/application/meters.go
@@ -16,13 +16,13 @@
 package application
 
 import (
+	"context"
 	"encoding/json"
 	"errors"
-	"context"
 	"sync"
 
-	cntlr "voltha-go-controller/internal/pkg/controller"
 	"voltha-go-controller/database"
+	cntlr "voltha-go-controller/internal/pkg/controller"
 	"voltha-go-controller/internal/pkg/of"
 	"voltha-go-controller/log"
 )
@@ -72,13 +72,13 @@
 // The ID is generated by the VOLT application
 type VoltMeter struct {
 	Name               string
+	Version            string
 	ID                 uint32
 	Fir                uint32
 	Air                uint32
 	Eir                uint32
 	BurstSize          uint32
 	AssociatedServices uint32
-	Version            string
 	Cir                uint32
 	Cbs                uint32
 	Pir                uint32
@@ -162,7 +162,7 @@
 		vm.Air = 0
 	}
 
-	//Set Pir & Pbs
+	// Set Pir & Pbs
 	var pir uint32
 	var pbs uint32
 	if vm.Pir != 0 {
@@ -186,7 +186,7 @@
 	logger.Infow(ctx, "Meter Config", log.Fields{"Cir": vm.Cir, "Air": vm.Air, "Pir": vm.Pir, "Gir": vm.Gir, "Eir": vm.Eir})
 	logger.Infow(ctx, "Meter Burst Config", log.Fields{"Cbs": vm.Cbs, "Pbs": vm.Pbs})
 	logger.Infow(ctx, "Meter Burst Oper", log.Fields{"Pir": pir, "Pbs": pbs})
-	//Set Air
+	// Set Air
 	// Air is used in place of Gir only if Gir is
 	// not present and Air is not 0
 	if vm.Air != 0 {
@@ -243,7 +243,6 @@
 
 // AddMeterProf to add the meter profile name as key
 func (va *VoltApplication) AddMeterProf(cntx context.Context, cfg VoltMeter) {
-
 	mm := &va.MeterMgr
 	if _, ok := mm.GetMeterByName(cfg.Name); ok {
 		logger.Warnw(ctx, "Meter profile exists", log.Fields{"Name": cfg.Name})
@@ -251,8 +250,8 @@
 	}
 
 	mm.LastMeterID++
-	//FIX-ME: Hardcoded the meter-id temp till meter delete is introduced
-	//Restriction: Only one meter profile should be used across all services
+	// FIX-ME: Hardcoded the meter-id temp till meter delete is introduced
+	// Restriction: Only one meter profile should be used across all services
 	//	id := uint32(1) //mm.LastMeterId
 	id := mm.LastMeterID
 	cfg.ID = id
@@ -295,7 +294,6 @@
 
 // DeleteFromDevice to delete meter from the device
 func (vm *VoltMeter) DeleteFromDevice(port string, device string) {
-
 	meter := of.NewMeter(vm.ID)
 
 	logger.Debugw(ctx, "Delete meter from device", log.Fields{"Id": vm.ID, "meter": *meter})
@@ -317,7 +315,7 @@
 			log.Fields{"MeterProfile": name, "serviceCount": cfg.AssociatedServices})
 		return errors.New("Service reference is not 0")
 	}
-	//TODO : delete from all devices
+	// TODO : delete from all devices
 	delmeterFromDevice := func(key interface{}, value interface{}) bool {
 		device := key.(string)
 		port, _ := GetApplication().GetNniPort(device)
@@ -326,7 +324,7 @@
 	}
 	va.DevicesDisc.Range(delmeterFromDevice)
 	cfg.DelFromDb(cntx)
-	//Delete meter from device will be invoked by caller separately
+	// Delete meter from device will be invoked by caller separately
 	mm.DelMeter(cfg)
 	return nil
 }
diff --git a/internal/pkg/application/minor_upgrade.go b/internal/pkg/application/minor_upgrade.go
index a0bba15..4d6b3d6 100644
--- a/internal/pkg/application/minor_upgrade.go
+++ b/internal/pkg/application/minor_upgrade.go
@@ -16,21 +16,22 @@
 package application
 
 import (
-	"errors"
 	"context"
+	"errors"
 	"net"
-	"voltha-go-controller/internal/pkg/types"
 
 	"strings"
 
-	"github.com/google/gopacket/layers"
 	"voltha-go-controller/database"
+	common "voltha-go-controller/internal/pkg/types"
 	"voltha-go-controller/log"
+
+	"github.com/google/gopacket/layers"
 )
 
 type paramsUpdationFunc func(cntx context.Context, hash string, value interface{}) error
 
-//map to store conversion functions
+// map to store conversion functions
 var updationMap = map[string]paramsUpdationFunc{
 	database.VnetPath:       updateVnets,
 	database.VpvPath:        updateVpvs,
@@ -53,43 +54,42 @@
 	return nil
 }
 
-//This function modifyies the old data as per current version requirement and also
-//returns the new path on which the modified data has to be written
+// This function modifyies the old data as per current version requirement and also
+// returns the new path on which the modified data has to be written
 func updateServices(cntx context.Context, hash string, value interface{}) error {
 	param := value.(*VoltService)
 	param.VnetID = VnetKey(param.SVlan, param.CVlan, param.UniVlan)
 	return nil
 }
 
-//This function modifyies the old data as per current version requirement and also
-//returns the new path on which the modified data has to be written
+// This function modifyies the old data as per current version requirement and also
+// returns the new path on which the modified data has to be written
 func updateVnets(cntx context.Context, hash string, value interface{}) error {
 	param := value.(*VoltVnet)
 	newKey := VnetKey(param.SVlan, param.CVlan, param.UniVlan)
 	if newKey != hash {
-		//Delete the older key
+		// Delete the older key
 		_ = db.DelVnet(cntx, hash)
 	} else {
-		//Update SVlan Tag Protocol id param with default valud if not present
+		// Update SVlan Tag Protocol id param with default valud if not present
 		if param.SVlanTpid == 0 {
 			param.SVlanTpid = layers.EthernetTypeDot1Q
 		}
 	}
 	param.Name = newKey
 	if param.DevicesList == nil || len(param.DevicesList) == 0 {
-		param.DevicesList = append(param.DevicesList, "") //Empty OLT serial number as of now since submgr won't have proper serial num
+		param.DevicesList = append(param.DevicesList, "") // Empty OLT serial number as of now since submgr won't have proper serial num
 	}
 	return nil
 }
 
-//This function modifyies the old data as per current version requirement and also
-//returns the new path on which the modified data has to be written
+// This function modifyies the old data as per current version requirement and also
+// returns the new path on which the modified data has to be written
 func updateVpvs(cntx context.Context, hash string, value interface{}) error {
-
 	//var param VoltPortVnet
 	param := value.(*VoltPortVnet)
 
-	//Update SVlan Tag Protocol id param with default valud if not present
+	// Update SVlan Tag Protocol id param with default valud if not present
 	if param.SVlanTpid == 0 {
 		param.SVlanTpid = layers.EthernetTypeDot1Q
 	}
@@ -99,9 +99,9 @@
 		return nil
 	}
 
-	//Add the vpv under new path
+	// Add the vpv under new path
 	param.WriteToDb(cntx)
-	//delete the older path
+	// delete the older path
 	fullPath := database.BasePath + database.VpvPath + hash
 	if err := db.Del(cntx, fullPath); err != nil {
 		logger.Errorw(ctx, "Vpv Delete from DB failed", log.Fields{"Error": err, "key": fullPath})
@@ -112,11 +112,10 @@
 func updateMvlans(cntx context.Context, hash string, value interface{}) error {
 	param := value.(*MvlanProfile)
 	if param.DevicesList == nil || len(param.DevicesList) == 0 {
-		param.DevicesList = make(map[string]OperInProgress) //Empty OLT serial number as of now since submgr won't have proper serial num
+		param.DevicesList = make(map[string]OperInProgress) // Empty OLT serial number as of now since submgr won't have proper serial num
 		if err := param.WriteToDb(cntx); err != nil {
 			logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": param.Name})
 		}
-
 	}
 	if _, ok := param.Groups[common.StaticGroup]; ok {
 		param.Groups[common.StaticGroup].IsStatic = true
@@ -124,10 +123,9 @@
 	return nil
 }
 
-//This function modifyies the old Igmp Group data as per current version requirement and also
-//returns the new path on which the modified data has to be written
+// This function modifyies the old Igmp Group data as per current version requirement and also
+// returns the new path on which the modified data has to be written
 func updateIgmpGroups(cntx context.Context, hash string, value interface{}) error {
-
 	ig := value.(*IgmpGroup)
 	logger.Infow(ctx, "Group Data Migration", log.Fields{"ig": ig, "GroupAddr": ig.GroupAddr, "hash": hash})
 	if ig.GroupAddr == nil {
@@ -140,8 +138,8 @@
 	return nil
 }
 
-//This function modifyies the old Igmp  Device data as per current version requirement and also
-//returns the new path on which the modified data has to be written
+// This function modifyies the old Igmp  Device data as per current version requirement and also
+// returns the new path on which the modified data has to be written
 func updateIgmpDevices(cntx context.Context, hash string, value interface{}) error {
 	igd := value.(*IgmpGroupDevice)
 	logger.Infow(ctx, "Group Device Migration", log.Fields{"igd": igd, "GroupAddr": igd.GroupAddr, "hash": hash})
@@ -150,14 +148,14 @@
 	}
 	if err := igd.WriteToDb(cntx); err != nil {
 		logger.Errorw(ctx, "Igmp group device Write to DB failed", log.Fields{"Device": igd.Device,
-					"GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
+			"GroupName": igd.GroupName, "GroupAddr": igd.GroupAddr.String()})
 	}
 
 	return nil
 }
 
-//This function modifyies the old Igmp  Profile data as per current version requirement and also
-//returns the new path on which the modified data has to be written
+// This function modifyies the old Igmp  Profile data as per current version requirement and also
+// returns the new path on which the modified data has to be written
 func updateIgmpProfiles(cntx context.Context, hash string, value interface{}) error {
 	igmpProfile := value.(*IgmpProfile)
 	logger.Infow(ctx, "IGMP Profile Migration", log.Fields{"igmpProfile": igmpProfile, "hash": hash})
@@ -165,7 +163,6 @@
 }
 
 func (ig *IgmpGroup) migrateIgmpDevices(cntx context.Context) {
-
 	devices, _ := db.GetPrevIgmpDevices(cntx, ig.Mvlan, ig.GroupName)
 	logger.Infow(ctx, "Migratable Devices", log.Fields{"Devices": devices})
 	for _, device := range devices {
@@ -192,11 +189,9 @@
 }
 
 func (igd *IgmpGroupDevice) migrateIgmpChannels(cntx context.Context) {
-
 	channels, _ := db.GetPrevIgmpChannels(cntx, igd.GroupName, igd.Device)
 	logger.Infow(ctx, "Migratable Channels", log.Fields{"Channels": channels})
 	for _, channel := range channels {
-
 		b, ok := channel.Value.([]byte)
 		if !ok {
 			logger.Warn(ctx, "The value type is not []byte")
@@ -220,11 +215,9 @@
 }
 
 func (igc *IgmpGroupChannel) migrateIgmpPorts(cntx context.Context) {
-
 	ports, _ := db.GetPrevIgmpRcvrs(cntx, igc.GroupAddr, igc.Device)
 	logger.Infow(ctx, "Migratable Ports", log.Fields{"Ports": ports})
 	for _, port := range ports {
-
 		b, ok := port.Value.([]byte)
 		if !ok {
 			logger.Warn(ctx, "The value type is not []byte")
diff --git a/internal/pkg/application/pppoeia.go b/internal/pkg/application/pppoeia.go
index 2d50033..8b62760 100644
--- a/internal/pkg/application/pppoeia.go
+++ b/internal/pkg/application/pppoeia.go
@@ -11,7 +11,7 @@
 * 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 application
 
@@ -87,9 +87,9 @@
 // to the network. It supports two VLANs as its identify. If a single VLAN or
 // no VLAN is to be used, those two should be passed as 4096 (VlanNone)
 type PppoeIaRelayVnet struct {
+	sessions  *util.ConcurrentMap //map[[6]byte]IPppoeIaSession
 	OuterVlan uint16
 	InnerVlan uint16
-	sessions  *util.ConcurrentMap //map[[6]byte]IPppoeIaSession
 }
 
 // PppoeIaNetworks : PppoeIa Networks hosts different PppoeIa networks that in turn hold the PppoeIa
@@ -154,7 +154,6 @@
 
 // delPppoeIaSessions to delete pppoeia sessions
 func delPppoeIaSessions(addr net.HardwareAddr, outervlan of.VlanType, innervlan of.VlanType) {
-
 	var key [6]byte
 	if addr == nil || !NonZeroMacAddress(addr) {
 		logger.Warnw(ctx, "Invalid MAC address", log.Fields{"Addr": addr})
@@ -184,7 +183,6 @@
 
 // GetVnetForNni to get vnet for nni port
 func GetVnetForNni(addr net.HardwareAddr, cvlan of.VlanType, svlan of.VlanType, pbit uint8) (*VoltPortVnet, error) {
-
 	var err error
 	var session IPppoeIaSession
 	logger.Infow(ctx, "Mac Obtained MAC: ", log.Fields{"Addr": addr})
@@ -217,7 +215,6 @@
 // into the packet. This happens as the request is relayed to the
 // PppoeIa servers on the NNI
 func AddIaOption(svc *VoltService, pppoe *layers.PPPoE) {
-
 	//NOTE : both cID and rID should not be empty if this function is called
 	var data []byte
 	cID := svc.GetCircuitID()
@@ -281,7 +278,6 @@
 // common map. The key for retrieval includes the VLAN tags in the
 // the packet and the MAC address of the client.
 func (va *VoltApplication) ProcessDsPppoeIaPacket(cntx context.Context, device string, port string, pkt gopacket.Packet) {
-
 	// Retrieve the layers to build the outgoing packet. It is not
 	// possible to add/remove layers to the existing packet and thus
 	// the lyayers are extracted to build the outgoing packet
@@ -433,7 +429,7 @@
 	}
 
 	if vpv.PppoeIa {
-		//Maintain the session MAC as learnt MAC, since MAC is required for deletion of PPPoE session
+		// Maintain the session MAC as learnt MAC, since MAC is required for deletion of PPPoE session
 		if msgType == layers.PPPoECodePADI || msgType == layers.PPPoECodePADR {
 			if !util.MacAddrsMatch(vpv.MacAddr, eth.SrcMAC) {
 				expectedPort := va.GetMacInPortMap(eth.SrcMAC)
@@ -517,7 +513,6 @@
 	if err := cntlr.GetController().PacketOutReq(device, outport, port, buff.Bytes(), false); err != nil {
 		logger.Warnw(ctx, "PacketOutReq Failed", log.Fields{"Device": device, "Error": err})
 	}
-
 }
 
 // ProcessPPPoEIaPacket to process Pppoeia packet
@@ -572,12 +567,12 @@
 
 // PppoeIaPacketTask : Task to add or delete flows of a service
 type PppoeIaPacketTask struct {
-	taskID    uint8
 	ctx       context.Context
 	pkt       gopacket.Packet
 	device    string
 	port      string
 	timestamp string
+	taskID    uint8
 }
 
 // NewPppoeIaPacketTask constructor for PppoeIaPacketTask
diff --git a/internal/pkg/application/service.go b/internal/pkg/application/service.go
index e129b48..e6e81c3 100644
--- a/internal/pkg/application/service.go
+++ b/internal/pkg/application/service.go
@@ -51,106 +51,102 @@
 // UniVlan -	The VLAN of the packets entering the UNI of ONU
 // CVlan -	The VLAN to transalate to/from on the PON link
 // SVlan -	The outer VLAN to be used on the NNI of OLT.
-//       -	In general, 4096 is used as NO VLAN for all the above
-// SVlanTpid - SVlan Tag Protocl Identifier
+// -	In general, 4096 is used as NO VLAN for all the above
+// SVlanTpid - SVlan Tag Protocol Identifier
 // Pbits -      Each bit of uint8 represents one p-bit. MSB is pbit 7
 // DhcpRelay -	Whether it is turned on/off
 // CircuitId -	The circuit id to be used with DHCP relay. Unused otherwise
 // RemoveId - 	Same as above
 // Port -	The access port for the service. Each service has a single access
-//		port. The converse is not always true
+// port. The converse is not always true
 // MacLearning - If MAC learning is turned on, the MAC address learned from the
-//		the service activation is used in programming flows
+// the service activation is used in programming flows
 // MacAddress -	The MAC hardware address learnt on the UNI interface
 // MacAddresses - Not yet implemented. To be used to learn more MAC addresses
 type VoltServiceCfg struct {
-	Name                       string
-	UniVlan                    of.VlanType
-	CVlan                      of.VlanType
-	SVlan                      of.VlanType
-	SVlanTpid                  layers.EthernetType
-	MacAddr                    net.HardwareAddr
 	Pbits                      []of.PbitType
-	UsPonCTagPriority          of.PbitType
-	UsPonSTagPriority          of.PbitType
-	DsPonCTagPriority          of.PbitType
-	DsPonSTagPriority          of.PbitType
-	DsRemarkPbitsMap           map[int]int // Ex: Remark case {0:0,1:0} and No-remark case {1:1}
-	TechProfileID              uint16
+	Name                       string
 	CircuitID                  string
-	RemoteID                   []byte
 	Port                       string
-	PonPort                    uint32
-	MacLearning                MacLearningType
-	IsOption82Disabled         bool
-	IgmpEnabled                bool
-	McastService               bool
-	ONTEtherTypeClassification int
-	VlanControl                VlanControl
 	UsMeterProfile             string
 	DsMeterProfile             string
 	AggDsMeterProfile          string
 	VnetID                     string
 	MvlanProfileName           string
 	RemoteIDType               string
-	SchedID                    int
-	AllowTransparent           bool
-	EnableMulticastKPI         bool
 	DataRateAttr               string
+	ServiceType                string
+	DsRemarkPbitsMap           map[int]int // Ex: Remark case {0:0,1:0} and No-remark case {1:1}
+	RemoteID                   []byte
+	MacAddr                    net.HardwareAddr
+	ONTEtherTypeClassification int
+	SchedID                    int
+	Trigger                    ServiceTrigger
+	MacLearning                MacLearningType
+	PonPort                    uint32
 	MinDataRateUs              uint32
 	MinDataRateDs              uint32
 	MaxDataRateUs              uint32
 	MaxDataRateDs              uint32
+	TechProfileID              uint16
+	SVlanTpid                  layers.EthernetType
+	UniVlan                    of.VlanType
+	CVlan                      of.VlanType
+	SVlan                      of.VlanType
+	UsPonCTagPriority          of.PbitType
+	UsPonSTagPriority          of.PbitType
+	DsPonSTagPriority          of.PbitType
+	DsPonCTagPriority          of.PbitType
+	VlanControl                VlanControl
+	IsOption82Disabled         bool
+	IgmpEnabled                bool
+	McastService               bool
+	AllowTransparent           bool
+	EnableMulticastKPI         bool
 	IsActivated                bool
-	Trigger                    ServiceTrigger
-	ServiceType                string
 }
 
 // VoltServiceOper structure
 type VoltServiceOper struct {
+	Metadata        interface{}
+	PendingFlows    map[string]bool
+	AssociatedFlows map[string]bool
+	BwAvailInfo     string
 	//MacLearning  bool
 	//MacAddr      net.HardwareAddr
-	Device   string
-	Ipv4Addr net.IP
-	Ipv6Addr net.IP
-
-	UsMeterID    uint32
-	DsMeterID    uint32
-	AggDsMeterID uint32
-
-	//Multiservice-Fix
+	Device           string
+	Ipv4Addr         net.IP
+	Ipv6Addr         net.IP
+	ServiceLock      sync.RWMutex `json:"-"`
+	UsMeterID        uint32
+	DsMeterID        uint32
+	AggDsMeterID     uint32
+	UpdateInProgress bool
+	DeleteInProgress bool
+	ForceDelete      bool
+	// Multiservice-Fix
 	UsHSIAFlowsApplied bool
 	DsHSIAFlowsApplied bool
 	UsDhcpFlowsApplied bool
 	DsDhcpFlowsApplied bool
 	IgmpFlowsApplied   bool
 	Icmpv6FlowsApplied bool
-
-	ServiceLock      sync.RWMutex `json:"-"`
-	PendingFlows     map[string]bool
-	AssociatedFlows  map[string]bool
-	DeleteInProgress bool
-	ForceDelete      bool
-	BwAvailInfo      string
-
-	UpdateInProgress bool
-	Metadata         interface{}
 }
 
 // VoltService structure
 type VoltService struct {
-	VoltServiceCfg
 	VoltServiceOper
 	Version string
+	VoltServiceCfg
 }
 
-//ServiceTrigger - Service activation trigger
+// ServiceTrigger - Service activation trigger
 type ServiceTrigger int
 
 const (
-	//NBActivate - Service added due to NB Action
+	// NBActivate - Service added due to NB Action
 	NBActivate ServiceTrigger = 0
-	//ServiceVlanUpdate - Service added due to Svlan Update
+	// ServiceVlanUpdate - Service added due to Svlan Update
 	ServiceVlanUpdate ServiceTrigger = 1
 )
 
@@ -160,7 +156,7 @@
 	VnetMutex        sync.Mutex `json:"-"`
 }
 
-//MigrateServiceMetadata - migrate services request metadata
+// MigrateServiceMetadata - migrate services request metadata
 type MigrateServiceMetadata struct {
 	NewVnetID string
 	RequestID string
@@ -188,7 +184,6 @@
 
 // WriteToDb commit a service to the DB if service delete is not in-progress
 func (vs *VoltService) WriteToDb(cntx context.Context) {
-
 	vs.ServiceLock.RLock()
 	defer vs.ServiceLock.RUnlock()
 
@@ -199,7 +194,7 @@
 	vs.ForceWriteToDb(cntx)
 }
 
-//ForceWriteToDb force commit a service to the DB
+// ForceWriteToDb force commit a service to the DB
 func (vs *VoltService) ForceWriteToDb(cntx context.Context) {
 	b, err := json.Marshal(vs)
 
@@ -220,8 +215,8 @@
 // DelFromDb delete a service from DB
 func (vs *VoltService) DelFromDb(cntx context.Context) {
 	logger.Debugw(ctx, "Deleting Service from DB", log.Fields{"Name": vs.Name})
-	//TODO - Need to understand and delete the second call
-	//Calling twice has worked though don't know why
+	// TODO - Need to understand and delete the second call
+	// Calling twice has worked though don't know why
 	_ = db.DelService(cntx, vs.Name)
 	_ = db.DelService(cntx, vs.Name)
 }
@@ -277,7 +272,7 @@
 	}
 }
 
-//DelHsiaFlows - Deletes US & DS HSIA Flows for the service
+// DelHsiaFlows - Deletes US & DS HSIA Flows for the service
 func (vs *VoltService) DelHsiaFlows(cntx context.Context) {
 	if err := vs.DelUsHsiaFlows(cntx); err != nil {
 		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
@@ -311,7 +306,6 @@
 
 // AddUsHsiaFlows - Add US HSIA Flows for the service
 func (vs *VoltService) AddUsHsiaFlows(cntx context.Context) error {
-
 	if vs.DeleteInProgress || vs.UpdateInProgress {
 		logger.Errorw(ctx, "Ignoring US HSIA Flow Push, Service deleteion In-Progress", log.Fields{"Device": vs.Device, "Service": vs.Name})
 		return nil
@@ -331,14 +325,14 @@
 
 		vs.Device = device.Name
 		/* In case of DPU_MGMT_TRAFFIC the meters will be configured before US flow creation*/
-		if vs.ServiceType != DPU_MGMT_TRAFFIC {
+		if vs.ServiceType != DpuMgmtTraffic {
 			va.AddMeterToDevice(vs.Port, device.Name, vs.UsMeterID, 0)
 			va.AddMeterToDevice(vs.Port, device.Name, vs.DsMeterID, vs.AggDsMeterID)
 		}
 		logger.Infow(ctx, "Adding HSIA flows", log.Fields{"Name": vs.Name})
 		pBits := vs.Pbits
 
-		//If no pbits configured for service, hence add PbitNone for flows
+		// If no pbits configured for service, hence add PbitNone for flows
 		if len(vs.Pbits) == 0 {
 			pBits = append(pBits, PbitMatchNone)
 		}
@@ -441,7 +435,6 @@
 
 // DelUsHsiaFlows - Deletes US HSIA Flows for the service
 func (vs *VoltService) DelUsHsiaFlows(cntx context.Context) error {
-
 	logger.Infow(ctx, "Removing US HSIA Services", log.Fields{"Services": vs.Name})
 	if vs.UsHSIAFlowsApplied || vgcRebooted {
 		device, err := GetApplication().GetDeviceFromPort(vs.Port)
@@ -453,7 +446,7 @@
 		logger.Infow(ctx, "Removing HSIA flows", log.Fields{"Name": vs.Name})
 		pBits := vs.Pbits
 
-		//If no pbits configured for service, hence add PbitNone for flows
+		// If no pbits configured for service, hence add PbitNone for flows
 		if len(vs.Pbits) == 0 {
 			pBits = append(pBits, PbitMatchNone)
 		}
@@ -479,7 +472,6 @@
 
 // DelDsHsiaFlows - Deletes DS HSIA Flows for the service
 func (vs *VoltService) DelDsHsiaFlows(cntx context.Context) error {
-
 	logger.Infow(ctx, "Removing DS HSIA Services", log.Fields{"Services": vs.Name})
 	if vs.DsHSIAFlowsApplied || vgcRebooted {
 		device, err := GetApplication().GetDeviceFromPort(vs.Port)
@@ -490,7 +482,7 @@
 
 		logger.Infow(ctx, "Removing HSIA flows", log.Fields{"Name": vs.Name})
 		var matchPbit int
-		//If no pbits configured for service, hence add PbitNone for flows
+		// If no pbits configured for service, hence add PbitNone for flows
 		if len(vs.DsRemarkPbitsMap) == 0 {
 			dsflows, err := vs.BuildDsHsiaFlows(of.PbitType(PbitMatchNone))
 			if err != nil {
@@ -531,7 +523,7 @@
 		}
 		vs.DsHSIAFlowsApplied = false
 	}
-	logger.Infow(ctx, "Deleted HSIA DS flows from DB successfuly", log.Fields{"ServiceName": vs.Name})
+	logger.Infow(ctx, "Deleted HSIA DS flows from DB successfully", log.Fields{"ServiceName": vs.Name})
 	// Post HSIA configuration success indication on message bus
 	vs.WriteToDb(cntx)
 	return nil
@@ -563,7 +555,7 @@
 	remarkPbit, remarkExists := vs.DsRemarkPbitsMap[int(pbits)]
 
 	generateDSCookie := func(vlan of.VlanType, valToShift uint64) uint64 {
-		//| 12-bit cvlan/UniVlan | 4 bits action pbit | <32-bits uniport>| 16-bits HSIA mask OR flow mask OR pbit |
+		// | 12-bit cvlan/UniVlan | 4 bits action pbit | <32-bits uniport>| 16-bits HSIA mask OR flow mask OR pbit |
 		cookie := uint64(vlan)<<52 + uint64(actnPbit)<<48 + uint64(outport)<<16 | of.HsiaFlowMask
 		cookie = cookie | of.DsFlowMask
 		cookie = cookie + (valToShift << 4) + uint64(pbits)
@@ -652,7 +644,7 @@
 			"subflow": subflow1})
 	}
 
-	//Add Table-1 flow that deals with inner VLAN at the ONU
+	// Add Table-1 flow that deals with inner VLAN at the ONU
 	{
 		subflow2 := of.NewVoltSubFlow()
 		subflow2.SetTableID(1)
@@ -736,10 +728,10 @@
 		subflow1.SetGoToTable(1)
 		subflow1.SetInPort(inport)
 
-		if vs.ServiceType == DPU_MGMT_TRAFFIC {
+		if vs.ServiceType == DpuMgmtTraffic {
 			subflow1.SetMatchPbit(vs.UsPonCTagPriority)
 			subflow1.SetPcp(vs.UsPonSTagPriority)
-		} else if vs.ServiceType == DPU_ANCP_TRAFFIC {
+		} else if vs.ServiceType == DpuAncpTraffic {
 			subflow1.SetPcp(vs.UsPonSTagPriority)
 		}
 		if err := vs.setUSMatchActionVlanT0(subflow1); err != nil {
@@ -773,7 +765,7 @@
 		logger.Infow(ctx, "Building upstream HSIA flow for T0", log.Fields{"cookie": subflow1.Cookie, "subflow": subflow1})
 	}
 
-	//Add Table-1 flow that deals with the outer vlan in pOLT
+	// Add Table-1 flow that deals with the outer vlan in pOLT
 	{
 		subflow2 := of.NewVoltSubFlow()
 		subflow2.SetTableID(1)
@@ -782,7 +774,7 @@
 		if err := vs.setUSMatchActionVlanT1(subflow2); err != nil {
 			return nil, err
 		}
-		if vs.ServiceType == DPU_MGMT_TRAFFIC {
+		if vs.ServiceType == DpuMgmtTraffic {
 			subflow2.SetMatchSrcMac(vs.MacAddr)
 		}
 		subflow2.SetInPort(inport)
@@ -817,7 +809,7 @@
 }
 
 func (vs *VoltService) generateUSCookie(vlan of.VlanType, valToShift uint64, inport uint32, pbits of.PbitType) uint64 {
-	//| 12-bit cvlan/UniVlan | 4 bits empty | <32-bits uniport>| 16-bits HSIA mask OR flow mask OR pbit |
+	// | 12-bit cvlan/UniVlan | 4 bits empty | <32-bits uniport>| 16-bits HSIA mask OR flow mask OR pbit |
 	cookie := uint64(vlan)<<52 + uint64(inport)<<16 | of.HsiaFlowMask
 	cookie = cookie | of.UsFlowMask
 	cookie = cookie + (valToShift << 4) + uint64(pbits)
@@ -990,7 +982,7 @@
 	var mmUs, mmDs *VoltMeter
 	var err error
 
-	//Take the  Device lock only in case of NB add request.
+	// Take the  Device lock only in case of NB add request.
 	// Allow internal adds since internal add happen only under
 	// 1. Restore Service from DB
 	// 2. Service Migration
@@ -1016,8 +1008,7 @@
 		vs.BwAvailInfo = oper.BwAvailInfo
 		vs.Device = oper.Device
 	} else {
-
-		//Sorting Pbit from highest
+		// Sorting Pbit from highest
 		sort.Slice(vs.Pbits, func(i, j int) bool {
 			return vs.Pbits[i] > vs.Pbits[j]
 		})
@@ -1080,12 +1071,11 @@
 	vs.WriteToDb(cntx)
 
 	if nil == oper {
-
 		if !vs.UsHSIAFlowsApplied {
 			vs.triggerServiceInProgressInd()
 		}
 
-		//Update meter profiles service count if service is being added from northbound
+		// Update meter profiles service count if service is being added from northbound
 		mmDs.AssociatedServices++
 		va.UpdateMeterProf(cntx, *mmDs)
 		if mmUs != nil {
@@ -1094,14 +1084,14 @@
 		}
 		//mmAg.AssociatedServices++
 		//va.UpdateMeterProf(*mmAg)
-		logger.Debugw(ctx, "northbound-service-add-sucessful", log.Fields{"ServiceName": vs.Name})
+		logger.Debugw(ctx, "northbound-service-add-successful", log.Fields{"ServiceName": vs.Name})
 	}
 
 	logger.Warnw(ctx, "Added Service to DB", log.Fields{"Name": vs.Name, "Port": (vs.Port), "ML": vs.MacLearning})
 	return nil
 }
 
-//DelServiceWithPrefix - Deletes service with the provided prefix.
+// DelServiceWithPrefix - Deletes service with the provided prefix.
 // Added for DT/TT usecase with sadis replica interface
 func (va *VoltApplication) DelServiceWithPrefix(cntx context.Context, prefix string) {
 	va.ServiceByName.Range(func(key, value interface{}) bool {
@@ -1124,7 +1114,6 @@
 
 // DelService delete a service form the application
 func (va *VoltApplication) DelService(cntx context.Context, name string, forceDelete bool, newSvc *VoltServiceCfg, serviceMigration bool) {
-
 	AppMutex.ServiceDataMutex.Lock()
 	defer AppMutex.ServiceDataMutex.Unlock()
 
@@ -1143,7 +1132,7 @@
 		return
 	}
 
-	//Set this to avoid race-condition during flow result processing
+	// Set this to avoid race-condition during flow result processing
 	vs.DeleteInProgress = true
 	vs.ForceDelete = forceDelete
 	vs.ForceWriteToDb(cntx)
@@ -1183,30 +1172,30 @@
 
 	if aggMeter, ok := va.MeterMgr.GetMeterByID(vs.AggDsMeterID); ok {
 		if nil == newSvc || (nil != newSvc && aggMeter.Name != newSvc.AggDsMeterProfile) {
-                       if aggMeter.AssociatedServices > 0 {
-                               aggMeter.AssociatedServices--
-                               logger.Infow(ctx, "Agg Meter assocaited services updated\n", log.Fields{"MeterID": aggMeter})
-                               va.UpdateMeterProf(cntx, *aggMeter)
-                       }
+			if aggMeter.AssociatedServices > 0 {
+				aggMeter.AssociatedServices--
+				logger.Infow(ctx, "Agg Meter associated services updated\n", log.Fields{"MeterID": aggMeter})
+				va.UpdateMeterProf(cntx, *aggMeter)
+			}
 		}
 	}
 	if dsMeter, ok := va.MeterMgr.GetMeterByID(vs.DsMeterID); ok {
-	       if nil == newSvc || (nil != newSvc && dsMeter.Name != newSvc.DsMeterProfile) {
-                       if dsMeter.AssociatedServices > 0 {
-                               dsMeter.AssociatedServices--
-                               logger.Infow(ctx, "DS Meter assocaited services updated\n", log.Fields{"MeterID": dsMeter})
-                               va.UpdateMeterProf(cntx, *dsMeter)
-                       }
+		if nil == newSvc || (nil != newSvc && dsMeter.Name != newSvc.DsMeterProfile) {
+			if dsMeter.AssociatedServices > 0 {
+				dsMeter.AssociatedServices--
+				logger.Infow(ctx, "DS Meter associated services updated\n", log.Fields{"MeterID": dsMeter})
+				va.UpdateMeterProf(cntx, *dsMeter)
+			}
 		}
 	}
 	if vs.AggDsMeterID != vs.UsMeterID {
 		if usMeter, ok := va.MeterMgr.GetMeterByID(vs.UsMeterID); ok {
-                       if nil == newSvc || (nil != newSvc && usMeter.Name != newSvc.UsMeterProfile) {
-                               if usMeter.AssociatedServices > 0 {
-                                       usMeter.AssociatedServices--
-                                       logger.Infow(ctx, "US Meter assocaited services updated\n", log.Fields{"MeterID": usMeter})
-                                       va.UpdateMeterProf(cntx, *usMeter)
-                               }
+			if nil == newSvc || (nil != newSvc && usMeter.Name != newSvc.UsMeterProfile) {
+				if usMeter.AssociatedServices > 0 {
+					usMeter.AssociatedServices--
+					logger.Infow(ctx, "US Meter associated services updated\n", log.Fields{"MeterID": usMeter})
+					va.UpdateMeterProf(cntx, *usMeter)
+				}
 			}
 		}
 	}
@@ -1215,17 +1204,16 @@
 		vs.CheckAndDeleteService(cntx)
 	}
 
-	//Delete the per service counter too
+	// Delete the per service counter too
 	va.ServiceCounters.Delete(name)
 	if vs.IgmpEnabled && vs.EnableMulticastKPI {
 		_ = db.DelAllServiceChannelCounter(cntx, name)
 	}
 }
 
-//AddFlows - Adds the flow to the service
+// AddFlows - Adds the flow to the service
 // Triggers flow addition after registering for flow indication event
 func (vs *VoltService) AddFlows(cntx context.Context, device *VoltDevice, flow *of.VoltFlow) error {
-
 	// Using locks instead of concurrent map for PendingFlows to avoid
 	// race condition during flow response indication processing
 	vs.ServiceLock.Lock()
@@ -1245,7 +1233,7 @@
 	return cntlr.GetController().AddFlows(cntx, vs.Port, device.Name, flow)
 }
 
-//FlowInstallSuccess - Called when corresponding service flow installation is success
+// FlowInstallSuccess - Called when corresponding service flow installation is success
 // If no more pending flows, HSIA indication wil be triggered
 func (vs *VoltService) FlowInstallSuccess(cntx context.Context, cookie string, bwAvailInfo of.BwAvailDetails) {
 	if vs.DeleteInProgress {
@@ -1273,7 +1261,6 @@
 	vs.WriteToDb(cntx)
 
 	if len(vs.PendingFlows) == 0 && vs.DsHSIAFlowsApplied {
-
 		device, err := GetApplication().GetDeviceFromPort(vs.Port)
 		if err != nil {
 			logger.Errorw(ctx, "Error Getting Device. Dropping HSIA Success indication to NB", log.Fields{"Reason": err.Error(), "Service": vs.Name, "Port": vs.Port})
@@ -1293,7 +1280,7 @@
 	logger.Infow(ctx, "Processed Service Flow Add Success Indication", log.Fields{"Cookie": cookie, "Service": vs.Name, "DsFlowsApplied": vs.DsHSIAFlowsApplied})
 }
 
-//FlowInstallFailure - Called when corresponding service flow installation is failed
+// FlowInstallFailure - Called when corresponding service flow installation is failed
 // Trigger service failure indication to NB
 func (vs *VoltService) FlowInstallFailure(cookie string, errorCode uint32, errReason string) {
 	vs.ServiceLock.RLock()
@@ -1308,10 +1295,9 @@
 	vs.triggerServiceFailureInd(errorCode, errReason)
 }
 
-//DelFlows - Deletes the flow from the service
+// 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 {
-
 	if !vs.ForceDelete {
 		// Using locks instead of concurrent map for AssociatedFlows to avoid
 		// race condition during flow response indication processing
@@ -1331,7 +1317,7 @@
 	return cntlr.GetController().DelFlows(cntx, vs.Port, device.Name, flow)
 }
 
-//CheckAndDeleteService - remove service from DB is there are no pending flows to be removed
+// CheckAndDeleteService - remove service from DB is there are no pending flows to be removed
 func (vs *VoltService) CheckAndDeleteService(cntx context.Context) {
 	if vs.DeleteInProgress && len(vs.AssociatedFlows) == 0 && !vs.DsHSIAFlowsApplied {
 		vs.DelFromDb(cntx)
@@ -1340,10 +1326,9 @@
 	}
 }
 
-//FlowRemoveSuccess - Called when corresponding service flow removal is success
+// FlowRemoveSuccess - Called when corresponding service flow removal is success
 // If no more associated flows, DelHSIA indication wil be triggered
 func (vs *VoltService) FlowRemoveSuccess(cntx context.Context, cookie string) {
-
 	// if vs.DeleteInProgress {
 	// 	logger.Warnw(ctx, "Skipping Flow Remove Success Notification. Service deletion in-progress", log.Fields{"Cookie": cookie, "Service": vs.Name})
 	// 	return
@@ -1364,7 +1349,6 @@
 	vs.WriteToDb(cntx)
 
 	if len(vs.AssociatedFlows) == 0 && !vs.DsHSIAFlowsApplied {
-
 		device := GetApplication().GetDevice(vs.Device)
 		if device == nil {
 			logger.Errorw(ctx, "Error Getting Device. Dropping DEL_HSIA Success indication to NB", log.Fields{"Service": vs.Name, "Port": vs.Port})
@@ -1376,7 +1360,7 @@
 
 		if vs.UpdateInProgress {
 			vs.updateVnetProfile(cntx, vs.Device)
-			//Not sending DEL_HSIA Indication since it wil be generated internally by SubMgr
+			// Not sending DEL_HSIA Indication since it wil be generated internally by SubMgr
 			return
 		}
 		logger.Infow(ctx, "All Flows removed for Service. Triggering Service De-activation Success indication to NB", log.Fields{"Service": vs.Name, "DeleteFlag": vs.DeleteInProgress})
@@ -1387,7 +1371,7 @@
 	logger.Infow(ctx, "Processed Service Flow Remove Success Indication", log.Fields{"Cookie": cookie, "Service": vs.Name, "Associated Flows": vs.AssociatedFlows, "DsFlowsApplied": vs.DsHSIAFlowsApplied})
 }
 
-//FlowRemoveFailure - Called when corresponding service flow installation is failed
+// FlowRemoveFailure - Called when corresponding service flow installation is failed
 // Trigger service failure indication to NB
 func (vs *VoltService) FlowRemoveFailure(cntx context.Context, cookie string, errorCode uint32, errReason string) {
 	vs.ServiceLock.RLock()
@@ -1476,7 +1460,6 @@
 
 // GetServiceNameFromCookie to get service name from cookie
 func (va *VoltApplication) GetServiceNameFromCookie(cookie uint64, portName string, pbit uint8, device string, tableMetadata uint64) *VoltService {
-
 	var vlan uint64
 	vlanControl := (tableMetadata >> 32) & 0xF
 
@@ -1484,7 +1467,7 @@
 		// Fetching UniVlan for vlanControl OLTCVLANOLTSVLAN
 		vlan = (tableMetadata >> 16) & 0xFFFF
 	} else {
-		//Fetching CVlan for other vlanControl
+		// Fetching CVlan for other vlanControl
 		vlan = cookie >> 52
 	}
 	logger.Infow(ctx, "Configured Params", log.Fields{"VlanControl": vlanControl, "vlan": vlan})
@@ -1499,19 +1482,19 @@
 	return service
 }
 
-//MigrateServicesReqStatus - update vnet request status
+// MigrateServicesReqStatus - update vnet request status
 type MigrateServicesReqStatus string
 
 const (
-	//MigrateSrvsReqInit constant
+	// MigrateSrvsReqInit constant
 	MigrateSrvsReqInit MigrateServicesReqStatus = "Init"
-	//MigrateSrvsReqDeactTriggered constant
+	// MigrateSrvsReqDeactTriggered constant
 	MigrateSrvsReqDeactTriggered MigrateServicesReqStatus = "Profiles Deactivated"
-	//MigrateSrvsReqCompleted constant
+	// MigrateSrvsReqCompleted constant
 	MigrateSrvsReqCompleted MigrateServicesReqStatus = "Update Complete"
 )
 
-//MigrateServicesRequest - update vnet request params
+// MigrateServicesRequest - update vnet request params
 type MigrateServicesRequest struct {
 	ID                  string
 	OldVnetID           string
@@ -1523,7 +1506,6 @@
 }
 
 func newMigrateServicesRequest(id string, oldVnetID string, newVnetID string, serviceMap map[string]bool, deviceID string) *MigrateServicesRequest {
-
 	var msr MigrateServicesRequest
 	msr.OldVnetID = oldVnetID
 	msr.NewVnetID = newVnetID
@@ -1534,7 +1516,7 @@
 	return &msr
 }
 
-//GetMsrKey - generates migrate service request key
+// GetMsrKey - generates migrate service request key
 func (msr *MigrateServicesRequest) GetMsrKey() string {
 	return msr.OldVnetID + "-" + msr.ID
 }
@@ -1547,7 +1529,7 @@
 // 	return (len(edr.AssociatedProfiles) == 0)
 // }
 
-//WriteToDB - writes the udpate vnet request details ot DB
+// WriteToDB - writes the udpate vnet request details ot DB
 func (msr *MigrateServicesRequest) WriteToDB(cntx context.Context) {
 	logger.Debugw(ctx, "Adding Migrate Service Request to DB", log.Fields{"OldVnet": msr.OldVnetID, "NewVnet": msr.NewVnetID, "Device": msr.DeviceID, "RequestID": msr.ID, "ServiceCount": len(msr.ServicesList)})
 	if b, err := json.Marshal(msr); err == nil {
@@ -1558,9 +1540,8 @@
 	}
 }
 
-//MigrateServices - updated vnet profile for services
+// MigrateServices - updated vnet profile for services
 func (va *VoltApplication) MigrateServices(cntx context.Context, serialNum string, reqID string, oldVnetID, newVnetID string, serviceList []string) error {
-
 	logger.Warnw(ctx, "Migrate Serviec Request Received", log.Fields{"SerialNum": serialNum, "RequestID": reqID, "OldVnet": oldVnetID, "NewVnet": newVnetID, "ServiceList": serviceList})
 	if _, ok := va.VnetsByName.Load(oldVnetID); !ok {
 		return errors.New("Old Vnet Id not found")
@@ -1588,12 +1569,11 @@
 	return nil
 }
 
-//ProcessMigrateServicesProfRequest - collects all associated profiles
+// ProcessMigrateServicesProfRequest - collects all associated profiles
 func (msr *MigrateServicesRequest) ProcessMigrateServicesProfRequest(cntx context.Context) {
 	va := GetApplication()
 	for srv, processed := range msr.ServicesList {
-
-		//Indicates new service is already created and only deletion of old one is pending
+		// Indicates new service is already created and only deletion of old one is pending
 		if processed {
 			va.DelService(cntx, srv, true, nil, true)
 			msr.serviceMigrated(cntx, srv)
@@ -1622,7 +1602,7 @@
 			vs.Metadata = metadata
 			vs.ServiceLock.Unlock()
 
-			//vpv flows will be removed when last service is removed from it and
+			// vpv flows will be removed when last service is removed from it and
 			// new vpv flows will be installed when new service is added
 			if vs.UsHSIAFlowsApplied {
 				vpv.DelTrapFlows(cntx)
@@ -1637,9 +1617,8 @@
 	}
 }
 
-//AddMigratingServices - store msr info to device obj
+// AddMigratingServices - store msr info to device obj
 func (d *VoltDevice) AddMigratingServices(msr *MigrateServicesRequest) {
-
 	var msrMap *util.ConcurrentMap
 	if msrMapIntf, ok := d.MigratingServices.Get(msr.OldVnetID); !ok {
 		msrMap = util.NewConcurrentMap()
@@ -1652,10 +1631,9 @@
 
 	d.MigratingServices.Set(msr.OldVnetID, msrMap)
 	logger.Infow(ctx, "1: DeviceMsr", log.Fields{"Device": d.Name, "Vnet": msr.OldVnetID, "Len": d.MigratingServices.Length()})
-
 }
 
-//getMigrateServicesRequest - fetches msr info from device
+// getMigrateServicesRequest - fetches msr info from device
 func (va *VoltApplication) getMigrateServicesRequest(deviceID string, oldVnetID string, requestID string) *MigrateServicesRequest {
 	if vd := va.GetDevice(deviceID); vd != nil {
 		logger.Infow(ctx, "2: DeviceMsr", log.Fields{"Device": deviceID, "Vnet": oldVnetID, "Len": vd.MigratingServices.Length()})
@@ -1665,14 +1643,13 @@
 			if msrObj, ok := msrList.Get(requestID); ok {
 				return msrObj.(*MigrateServicesRequest)
 			}
-
 		}
 	}
 	logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": deviceID})
 	return nil
 }
 
-//updateMigrateServicesRequest - Updates the device with updated msr
+// updateMigrateServicesRequest - Updates the device with updated msr
 func (va *VoltApplication) updateMigrateServicesRequest(deviceID string, oldVnetID string, requestID string, msr *MigrateServicesRequest) {
 	if vd := va.GetDevice(deviceID); vd != nil {
 		if msrList, ok := vd.MigratingServices.Get(oldVnetID); ok {
@@ -1683,10 +1660,9 @@
 	}
 }
 
-//updateVnetProfile - Called on flow process completion
-// Removes old service and creates new VPV & service with udpated vnet profile
+// updateVnetProfile - Called on flow process completion
+// Removes old service and creates new VPV & service with updated vnet profile
 func (vs *VoltService) updateVnetProfile(cntx context.Context, deviceID string) {
-
 	logger.Infow(ctx, "Update Vnet Profile Triggering", log.Fields{"Service": vs.Name, "US": vs.UsHSIAFlowsApplied, "DS": vs.DsHSIAFlowsApplied})
 
 	nvs := VoltService{}
@@ -1717,8 +1693,6 @@
 
 	metadata := vs.Metadata.(*MigrateServiceMetadata)
 	oldVnetID := vs.VnetID
-	nvs.VnetID = metadata.NewVnetID
-	id := metadata.RequestID
 	oldSrvName := vs.Name
 
 	if metadata == nil || metadata.NewVnetID == "" {
@@ -1726,7 +1700,10 @@
 		return
 	}
 
-	//First add the new service and then only delete the old service
+	nvs.VnetID = metadata.NewVnetID
+	id := metadata.RequestID
+
+	// First add the new service and then only delete the old service
 	// Since if post del service in case of pod crash or reboot, the service data will be lost
 	va := GetApplication()
 	msr := va.getMigrateServicesRequest(deviceID, oldVnetID, id)
@@ -1741,7 +1718,7 @@
 	svcName = svcName + strconv.FormatUint(uint64(vs.CVlan), 10) + "-"
 	nvs.Name = svcName + strconv.FormatUint(uint64(vs.TechProfileID), 10)
 
-	//TODO:Nav Pass a copy, not the pointer
+	// TODO:Nav Pass a copy, not the pointer
 	logger.Infow(ctx, "Add New Service Triggering", log.Fields{"Service": nvs.Name, "US": nvs.UsHSIAFlowsApplied, "DS": nvs.DsHSIAFlowsApplied, "DelFlag": nvs.DeleteInProgress})
 	if err := va.AddService(cntx, nvs.VoltServiceCfg, &nvs.VoltServiceOper); err != nil {
 		logger.Warnw(ctx, "Add New Service Failed", log.Fields{"Service": nvs.Name, "Error": err})
@@ -1758,10 +1735,9 @@
 	msr.serviceMigrated(cntx, oldSrvName)
 }
 
-//serviceMigrated - called on successful service updation
+// serviceMigrated - called on successful service updation
 // Removes the service entry from servicelist and deletes the request on process completion
 func (msr *MigrateServicesRequest) serviceMigrated(cntx context.Context, serviceName string) {
-
 	msr.MigrateServicesLock.Lock()
 	defer msr.MigrateServicesLock.Unlock()
 
@@ -1772,17 +1748,16 @@
 		return
 	}
 	msr.WriteToDB(cntx)
-	//TODO:Nav - Need for any Response to SubMgr?
+	// TODO:Nav - Need for any Response to SubMgr?
 }
 
-//TriggerPendingMigrateServicesReq - trigger pending service request
+// TriggerPendingMigrateServicesReq - trigger pending service request
 func (va *VoltApplication) TriggerPendingMigrateServicesReq(cntx context.Context, device string) {
 	va.FetchAndProcessAllMigrateServicesReq(cntx, device, storeAndProcessMigrateSrvRequest)
 }
 
-//FetchAndProcessAllMigrateServicesReq - fetch all pending migrate services req from DB and process based on provided func
+// FetchAndProcessAllMigrateServicesReq - fetch all pending migrate services req from DB and process based on provided func
 func (va *VoltApplication) FetchAndProcessAllMigrateServicesReq(cntx context.Context, device string, msrAction func(context.Context, *MigrateServicesRequest)) {
-
 	msrList, _ := db.GetAllMigrateServicesReq(cntx, device)
 	for _, msr := range msrList {
 		b, ok := msr.Value.([]byte)
@@ -1793,7 +1768,6 @@
 		msr := va.createMigrateServicesFromString(b)
 		msrAction(cntx, msr)
 		logger.Warnw(ctx, "Triggering Pending Migrate Services Req", log.Fields{"OldVnet": msr.OldVnetID, "NewVnet": msr.NewVnetID, "Device": device, "PendingProfiles": len(msr.ServicesList)})
-
 	}
 }
 
@@ -1802,21 +1776,20 @@
 	var msr MigrateServicesRequest
 	if err := json.Unmarshal(b, &msr); err == nil {
 		logger.Debugw(ctx, "Adding Migrate Services Request From Db", log.Fields{"Vlan": msr.OldVnetID})
-
 	} else {
 		logger.Warn(ctx, "Unmarshal failed")
 	}
 	return &msr
 }
 
-//storeAndProcessMigrateSrvRequest - stores the msr info in device obj and triggers req
+// storeAndProcessMigrateSrvRequest - stores the msr info in device obj and triggers req
 func storeAndProcessMigrateSrvRequest(cntx context.Context, msr *MigrateServicesRequest) {
 	d := GetApplication().GetDevice(msr.DeviceID)
 	d.AddMigratingServices(msr)
 	msr.ProcessMigrateServicesProfRequest(cntx)
 }
 
-//forceUpdateAllServices - force udpate services with new vnet profile
+// forceUpdateAllServices - force udpate services with new vnet profile
 func forceUpdateAllServices(cntx context.Context, msr *MigrateServicesRequest) {
 	for srv := range msr.ServicesList {
 		if vsIntf, ok := GetApplication().ServiceByName.Load(srv); ok {
@@ -1826,7 +1799,8 @@
 	_ = db.DelMigrateServicesReq(cntx, msr.DeviceID, msr.GetMsrKey())
 }
 
-//DeepEqualServicecfg - checks if the given service cfgs are same
+// nolint: gocyclo
+// DeepEqualServicecfg - checks if the given service cfgs are same
 func (va *VoltApplication) DeepEqualServicecfg(evs *VoltServiceCfg, nvs *VoltServiceCfg) bool {
 	if nvs.Name != evs.Name {
 		return false
@@ -1925,11 +1899,10 @@
 	return true
 }
 
-//TriggerAssociatedFlowDelete - re-trigger service flow delete for pending delete flows
+// TriggerAssociatedFlowDelete - re-trigger service flow delete for pending delete flows
 func (vs *VoltService) TriggerAssociatedFlowDelete(cntx context.Context) bool {
-
-	//Clear the Flows flag if already set
-	//This case happens only in case of some race condition
+	// Clear the Flows flag if already set
+	// This case happens only in case of some race condition
 	if vs.UsHSIAFlowsApplied {
 		if err := vs.DelUsHsiaFlows(cntx); err != nil {
 			logger.Errorw(ctx, "DelUsHsiaFlows Failed", log.Fields{"Device": vs.Device, "Service": vs.Name, "Error": err})
@@ -1953,7 +1926,7 @@
 		return false
 	}
 
-	//Trigger Flow Delete
+	// Trigger Flow Delete
 	for _, cookie := range cookieList {
 		if vd := GetApplication().GetDevice(vs.Device); vd != nil {
 			flow := &of.VoltFlow{}
@@ -1970,12 +1943,12 @@
 	return true
 }
 
-//triggerServiceInProgressInd - Indication is generated when Service is not provisioned after add serviec req from NB
+// triggerServiceInProgressInd - Indication is generated when Service is not provisioned after add serviec req from NB
 func (vs *VoltService) triggerServiceInProgressInd() {
 }
 
-// JsonMarshal wrapper function for json Marshal VoltService
-func (vs *VoltService) JsonMarshal() ([]byte, error) {
+// JSONMarshal wrapper function for json Marshal VoltService
+func (vs *VoltService) JSONMarshal() ([]byte, error) {
 	return json.Marshal(VoltService{
 		VoltServiceCfg: vs.VoltServiceCfg,
 		VoltServiceOper: VoltServiceOper{
@@ -2081,7 +2054,7 @@
 		// If svlan if provided, then the tags and tpID of service has to be matching
 		logger.Infow(ctx, "Service Deactivate Request ", log.Fields{"Device": deviceID, "Port": portNo})
 		if sVlan != of.VlanNone && (sVlan != vs.SVlan || cVlan != vs.CVlan || tpID != vs.TechProfileID) {
-			logger.Infow(ctx, "condition not matched", log.Fields{"Device": deviceID, "Port": portNo, "sVlan": sVlan, "cVlan":cVlan, "tpID": tpID})
+			logger.Infow(ctx, "condition not matched", log.Fields{"Device": deviceID, "Port": portNo, "sVlan": sVlan, "cVlan": cVlan, "tpID": tpID})
 			return true
 		}
 		if portNo == vs.Port && vs.IsActivated {
@@ -2096,7 +2069,7 @@
 				return true
 			}
 			p := device.GetPort(vs.Port)
-			if p != nil && (p.State == PortStateUp || !va.OltFlowServiceConfig.RemoveFlowsOnDisable){
+			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)
@@ -2113,15 +2086,15 @@
 	return nil
 }
 
-/* GetServicePbit to get first set bit in the pbit map
-   returns -1 : If configured to match on all pbits
-   returns 8  : If no pbits are configured
-   returns first pbit if specific pbit is configured */
+// GetServicePbit to get first set bit in the pbit map
+// returns -1 : If configured to match on all pbits
+// returns 8  : If no pbits are configured
+// returns first pbit if specific pbit is configured
 func (vs *VoltService) GetServicePbit() int {
 	if vs.IsPbitExist(of.PbitMatchAll) {
 		return -1
 	}
-	for pbit:= 0; pbit < int(of.PbitMatchNone); pbit++ {
+	for pbit := 0; pbit < int(of.PbitMatchNone); pbit++ {
 		if vs.IsPbitExist(of.PbitType(pbit)) {
 			return pbit
 		}
diff --git a/internal/pkg/application/timer.go b/internal/pkg/application/timer.go
index aa156a8..167f8ae 100644
--- a/internal/pkg/application/timer.go
+++ b/internal/pkg/application/timer.go
@@ -20,7 +20,7 @@
 	"time"
 )
 
-//TimerType - type of timer used
+// TimerType - type of timer used
 type TimerType string
 
 const (
@@ -57,7 +57,7 @@
 			case pendingPoolTimer:
 				va.removeExpiredGroups(cntx)
 			}
-		case <- timerChannels[timerType]:
+		case <-timerChannels[timerType]:
 			return
 		}
 	}
diff --git a/internal/pkg/application/util.go b/internal/pkg/application/util.go
index 866e12b..f157bf9 100644
--- a/internal/pkg/application/util.go
+++ b/internal/pkg/application/util.go
@@ -23,17 +23,17 @@
 )
 
 const (
-	//EtherType8100 - EtherType dot1q
+	// EtherType8100 - EtherType dot1q
 	EtherType8100 uint8 = 0
-	//EtherType88a8 - EtherType dot1ad
+	// EtherType88a8 - EtherType dot1ad
 	EtherType88a8 uint8 = 1
-	//EtherType9100 - EtherType dot1ad doubleTag
+	// EtherType9100 - EtherType dot1ad doubleTag
 	EtherType9100 uint8 = 2
-	//EtherType9200 - EtherType dot1q doubleTag
+	// EtherType9200 - EtherType dot1q doubleTag
 	EtherType9200 uint8 = 3
 )
 
-//GetMetadataForL2Protocol - returns metadata value for provide ethertype
+// GetMetadataForL2Protocol - returns metadata value for provide ethertype
 func GetMetadataForL2Protocol(etherType layers.EthernetType) (uint8, error) {
 	switch etherType {
 	case layers.EthernetTypeDot1Q:
@@ -50,11 +50,9 @@
 }
 
 func convertToUInt64(data string) uint64 {
-
 	value, err := strconv.ParseUint(data, 10, 64)
 	if err != nil {
 		return 0
 	}
 	return value
-
 }
diff --git a/internal/pkg/application/vnets.go b/internal/pkg/application/vnets.go
index 548879f..1817b5d 100644
--- a/internal/pkg/application/vnets.go
+++ b/internal/pkg/application/vnets.go
@@ -48,13 +48,13 @@
 	Radisys string = "Radisys"
 
 	// DPU_MGMT_TRAFFIC serviceType, vnetType constant
-	DPU_MGMT_TRAFFIC string = "DPU_MGMT_TRAFFIC"
+	DpuMgmtTraffic string = "DPU_MGMT_TRAFFIC"
 
 	// DPU_ANCP_TRAFFIC serviceType, vnetType constant
-	DPU_ANCP_TRAFFIC string = "DPU_ANCP_TRAFFIC"
+	DpuAncpTraffic string = "DPU_ANCP_TRAFFIC"
 
 	// FTTB_SUBSCRIBER_TRAFFIC serviceType, vnetType constant
-	FTTB_SUBSCRIBER_TRAFFIC string = "FTTB_SUBSCRIBER_TRAFFIC"
+	FttbSubscriberTraffic string = "FTTB_SUBSCRIBER_TRAFFIC"
 )
 
 var (
@@ -101,47 +101,47 @@
 
 // VnetConfig structure
 type VnetConfig struct {
+	CtrlPktPbitRemark          map[of.PbitType]of.PbitType
 	Name                       string
-	SVlan                      of.VlanType
-	CVlan                      of.VlanType
-	UniVlan                    of.VlanType
-	SVlanTpid                  layers.EthernetType
-	DhcpRelay                  bool
-	ArpLearning                bool
-	MacLearning                MacLearningType
-	PppoeIa                    bool
-	ONTEtherTypeClassification int
-	VlanControl                VlanControl
+	VnetType                   string
 	Encapsulation              string
+	DevicesList                []string //List of serial number of devices on which this vnet is applied
 	UsDhcpPbit                 []of.PbitType
 	DsDhcpPbit                 []of.PbitType
 	UsIGMPPbit                 []of.PbitType
 	DsIGMPPbit                 []of.PbitType
-	DevicesList                []string //List of serial number of devices on which this vnet is applied
-	AllowTransparent           bool
-	CtrlPktPbitRemark          map[of.PbitType]of.PbitType
+	ONTEtherTypeClassification int
+	MacLearning                MacLearningType
 	UsPonCTagPriority          of.PbitType
 	UsPonSTagPriority          of.PbitType
 	DsPonCTagPriority          of.PbitType
 	DsPonSTagPriority          of.PbitType
-	VnetType                   string
+	SVlan                      of.VlanType
+	CVlan                      of.VlanType
+	UniVlan                    of.VlanType
+	SVlanTpid                  layers.EthernetType
+	VlanControl                VlanControl
+	DhcpRelay                  bool
+	ArpLearning                bool
+	AllowTransparent           bool
+	PppoeIa                    bool
 }
 
 // VnetOper structure
 type VnetOper struct {
 	PendingDeleteFlow     map[string]map[string]bool
-	DeleteInProgress      bool
-	PendingDeviceToDelete string
-	VnetLock              sync.RWMutex    `json:"-"`
-	VnetPortLock          sync.RWMutex    `json:"-"`
 	AssociatedPorts       map[string]bool `json:"-"`
+	PendingDeviceToDelete string
+	VnetLock              sync.RWMutex `json:"-"`
+	VnetPortLock          sync.RWMutex `json:"-"`
+	DeleteInProgress      bool
 }
 
 // VoltVnet sructure
 type VoltVnet struct {
+	Version string
 	VnetConfig
 	VnetOper
-	Version string
 }
 
 const (
@@ -168,7 +168,7 @@
 	return &vv
 }
 
-//associatePortToVnet - associate a port to Vnet
+// associatePortToVnet - associate a port to Vnet
 func (vv *VoltVnet) associatePortToVnet(port string) {
 	vv.VnetPortLock.Lock()
 	if vv.AssociatedPorts == nil {
@@ -178,7 +178,7 @@
 	vv.VnetPortLock.Unlock()
 }
 
-//disassociatePortFromVnet - disassociate a port from Vnet and return true if the association map is empty
+// disassociatePortFromVnet - disassociate a port from Vnet and return true if the association map is empty
 func (vv *VoltVnet) disassociatePortFromVnet(cntx context.Context, device string, port string) {
 	vv.VnetPortLock.Lock()
 	delete(vv.AssociatedPorts, port)
@@ -210,7 +210,6 @@
 
 // WriteToDb commit the VNET to the database
 func (vv *VoltVnet) WriteToDb(cntx context.Context) {
-
 	if vv.DeleteInProgress {
 		logger.Warnw(ctx, "Skipping Redis Update for Vnet, Vnet delete in progress", log.Fields{"Vnet": vv.Name})
 		return
@@ -218,7 +217,7 @@
 	vv.ForceWriteToDb(cntx)
 }
 
-//ForceWriteToDb force commit a vnet to the DB
+// ForceWriteToDb force commit a vnet to the DB
 func (vv *VoltVnet) ForceWriteToDb(cntx context.Context) {
 	vv.VnetPortLock.RLock()
 	defer vv.VnetPortLock.RUnlock()
@@ -264,7 +263,6 @@
 
 // storeVnetConfig to store vnet config
 func (va *VoltApplication) storeVnetConfig(cfg VnetConfig, vv *VoltVnet) {
-
 	var vnetMap *util.ConcurrentMap
 
 	va.VnetsByTag.Store(VnetKey(cfg.SVlan, cfg.CVlan, cfg.UniVlan), vv)
@@ -293,7 +291,6 @@
 
 // AddVnet to add a VNET to the list of VNETs configured.
 func (va *VoltApplication) AddVnet(cntx context.Context, cfg VnetConfig, oper *VnetOper) error {
-
 	AppMutex.VnetMutex.Lock()
 	var vv *VoltVnet
 	devicesToHandle := []string{}
@@ -344,7 +341,7 @@
 	AppMutex.VnetMutex.Lock()
 	if vnetIntf, ok := va.VnetsByName.Load(name); ok {
 		vnet := vnetIntf.(*VoltVnet)
-		//Delete from mvp list
+		// Delete from mvp list
 		vnet.DevicesList = util.RemoveFromSlice(vnet.DevicesList, deviceSerialNum)
 
 		va.DeleteDevFlowForVlanFromDevice(cntx, vnet, deviceSerialNum)
@@ -362,11 +359,11 @@
 			}
 			vnet.VnetPortLock.RUnlock()
 		} else {
-			//Update the devicelist in db
+			// Update the devicelist in db
 			vnet.WriteToDb(cntx)
 		}
 	}
-	//TODO: if no vnets are present on device remove icmpv6 group from device
+	// TODO: if no vnets are present on device remove icmpv6 group from device
 	AppMutex.VnetMutex.Unlock()
 	return nil
 }
@@ -407,61 +404,61 @@
 
 // VoltPortVnet structure
 type VoltPortVnet struct {
+	PendingDeleteFlow          map[string]bool
+	servicesCount              *atomic.Uint64
+	services                   sync.Map
 	Device                     string
 	Port                       string
-	PonPort                    uint32
 	VnetName                   string
-	SVlan                      of.VlanType
-	CVlan                      of.VlanType
-	UniVlan                    of.VlanType
-	SVlanTpid                  layers.EthernetType
-	DhcpRelay                  bool
-	ArpRelay                   bool
-	PppoeIa                    bool
-	MacLearning                MacLearningType
-	DhcpStatus                 DhcpStatus
+	VnetType                   string
+	MvlanProfileName           string
+	Version                    string
 	DhcpExpiryTime             time.Time
 	Dhcp6ExpiryTime            time.Time
-	FlowsApplied               bool
-	services                   sync.Map
-	servicesCount              *atomic.Uint64
 	Ipv4Addr                   net.IP
 	Ipv6Addr                   net.IP
 	MacAddr                    net.HardwareAddr
 	LearntMacAddr              net.HardwareAddr
-	CircuitID                  []byte //Will not be used
-	RemoteID                   []byte //Will not be used
-	IsOption82Disabled         bool   //Will not be used
-	RelayState                 DhcpRelayState
-	PPPoeState                 PppoeIaState
-	RelayStatev6               Dhcpv6RelayState
-	IgmpEnabled                bool
-	IgmpFlowsApplied           bool
-	McastService               bool
+	CircuitID                  []byte       //Will not be used
+	RemoteID                   []byte       //Will not be used
+	VpvLock                    sync.Mutex   `json:"-"`
+	PendingFlowLock            sync.RWMutex `json:"-"`
+	SchedID                    int
 	ONTEtherTypeClassification int
-	VlanControl                VlanControl
-	MvlanProfileName           string
-	Version                    string
+	MacLearning                MacLearningType
+	PonPort                    uint32
+	McastUsMeterID             uint32
 	McastTechProfileID         uint16
 	McastPbit                  of.PbitType
-	McastUsMeterID             uint32
-	AllowTransparent           bool
-	VpvLock                    sync.Mutex `json:"-"`
-	SchedID                    int
-	DHCPv6DUID                 [MaxLenDhcpv6DUID]byte
-	PendingFlowLock            sync.RWMutex `json:"-"`
-	PendingDeleteFlow          map[string]bool
-	DeleteInProgress           bool
-	Blocked                    bool
+	SVlanTpid                  layers.EthernetType
 	DhcpPbit                   of.PbitType
 	UsPonCTagPriority          of.PbitType
 	UsPonSTagPriority          of.PbitType
 	DsPonCTagPriority          of.PbitType
 	DsPonSTagPriority          of.PbitType
-	VnetType                   string
+	SVlan                      of.VlanType
+	CVlan                      of.VlanType
+	UniVlan                    of.VlanType
+	VlanControl                VlanControl
+	RelayState                 DhcpRelayState
+	DhcpStatus                 DhcpStatus
+	PPPoeState                 PppoeIaState
+	RelayStatev6               Dhcpv6RelayState
+	DHCPv6DUID                 [MaxLenDhcpv6DUID]byte
+	DhcpRelay                  bool
+	ArpRelay                   bool
+	PppoeIa                    bool
+	DeleteInProgress           bool
+	Blocked                    bool
+	AllowTransparent           bool
+	IgmpEnabled                bool
+	IgmpFlowsApplied           bool
+	McastService               bool
+	FlowsApplied               bool
+	IsOption82Disabled         bool //Will not be used
 }
 
-//VlanControl vlan control type
+// VlanControl vlan control type
 type VlanControl uint8
 
 const (
@@ -524,10 +521,9 @@
 }
 
 func (vpv *VoltPortVnet) setDevice(device string) {
-
 	if vpv.Device != device && vpv.Device != "" {
 		GetApplication().DisassociateVpvsFromDevice(device, vpv)
-		//TEMP:
+		// TEMP:
 		vpv.printAssociatedVPVs(false)
 	}
 
@@ -535,11 +531,11 @@
 
 	vpv.Device = device
 	GetApplication().AssociateVpvsToDevice(device, vpv)
-	//TEMP:
+	// TEMP:
 	vpv.printAssociatedVPVs(true)
 }
 
-//TODO - Nav - Temp
+// TODO - Nav - Temp
 func (vpv *VoltPortVnet) printAssociatedVPVs(add bool) {
 	logger.Infow(ctx, "Start----Printing all associated VPV", log.Fields{"Device": vpv.Device, "Add": add})
 	if vMap := GetApplication().GetAssociatedVpvsForDevice(vpv.Device, vpv.SVlan); vMap != nil {
@@ -550,7 +546,6 @@
 		})
 	}
 	logger.Infow(ctx, "End----Printing all associated VPV", log.Fields{"Device": vpv.Device, "Add": add})
-
 }
 
 // GetCircuitID : The interface to be satisfied by the VoltPortVnet to be a DHCP relay
@@ -724,7 +719,6 @@
 
 // PushFlowsForPortVnet - triggers flow construction and push for provided VPV
 func (vpv *VoltPortVnet) PushFlowsForPortVnet(cntx context.Context, d *VoltDevice) {
-
 	vp := d.GetPort(vpv.Port)
 
 	//Ignore if UNI port is not found or not UP
@@ -753,7 +747,6 @@
 // changed. Thus, a reboot of ONT forces the new configuration to get
 // applied.
 func (vpv *VoltPortVnet) PortUpInd(cntx context.Context, device *VoltDevice, port string) {
-
 	if vpv.DeleteInProgress {
 		logger.Errorw(ctx, "Ignoring VPV Port UP Ind, VPV deleteion In-Progress", log.Fields{"Device": device, "Port": port, "Vnet": vpv.VnetName})
 		return
@@ -788,17 +781,17 @@
 		// DS HSIA flows are installed after learning the MAC.
 		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 != DPU_MGMT_TRAFFIC {
+		if !vpv.McastService && vpv.VnetType != DpuMgmtTraffic {
 			vpv.RangeOnServices(cntx, AddUsHsiaFlows)
 		}
-		if vpv.VnetType == DPU_MGMT_TRAFFIC {
+		if vpv.VnetType == DpuMgmtTraffic {
 			vpv.RangeOnServices(cntx, AddMeterToDevice)
 		}
 		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 == DPU_MGMT_TRAFFIC {
+			if vpv.VnetType == DpuMgmtTraffic {
 				vpv.RangeOnServices(cntx, AddUsHsiaFlows)
 			}
 			// US & DS DHCP, US HSIA flows are already installed
@@ -808,7 +801,6 @@
 				vpv.RangeOnServices(cntx, AddDsHsiaFlows)
 			}
 		}
-
 	} else {
 		// DHCP relay is not configured. This implies that the service must use
 		// 1:1 and does not require MAC learning. In a completely uncommon but
@@ -846,7 +838,6 @@
 // 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) {
-
 	if !nbRequest && !GetApplication().OltFlowServiceConfig.RemoveFlowsOnDisable {
 		logger.Info(ctx, "VPV Port DOWN Ind, Not deleting flows since RemoveOnDisable is disabled")
 		return
@@ -865,7 +856,6 @@
 // packets received from the network. Currently, DHCP packets are
 // only packets we learn the MAC address from
 func (vpv *VoltPortVnet) SetMacAddr(cntx context.Context, addr net.HardwareAddr) {
-
 	//Store Learnt MAC address and return if MACLearning is not enabled
 	vpv.LearntMacAddr = addr
 	if vpv.MacLearning == MacLearningNone || !NonZeroMacAddress(addr) ||
@@ -918,7 +908,7 @@
 	// Ds Hsia flows has to be pushed
 	if vpv.FlowsApplied {
 		// In case of DPU_MGMT_TRAFFIC install both US and DS Flows
-		if vpv.VnetType == DPU_MGMT_TRAFFIC {
+		if vpv.VnetType == DpuMgmtTraffic {
 			vpv.RangeOnServices(cntx, AddUsHsiaFlows)
 		}
 		// no HSIA flows for multicast service
@@ -950,7 +940,6 @@
 
 // MatchesPriority : If the VNET matches priority of the incoming packet with any service, return true. Else, return false
 func (vpv *VoltPortVnet) MatchesPriority(priority uint8) *VoltService {
-
 	var service *VoltService
 	pbitFound := false
 	matchpbitsFunc := func(key, value interface{}) bool {
@@ -973,7 +962,6 @@
 
 // GetRemarkedPriority : If the VNET matches priority of the incoming packet with any service, return true. Else, return false
 func (vpv *VoltPortVnet) GetRemarkedPriority(priority uint8) uint8 {
-
 	dsPbit := uint8(0)
 	matchpbitsFunc := func(key, value interface{}) bool {
 		svc := value.(*VoltService)
@@ -999,7 +987,6 @@
 // AddSvc adds a service on the VNET on a port. The addition is
 // triggered when NB requests for service addition
 func (vpv *VoltPortVnet) AddSvc(cntx context.Context, svc *VoltService) {
-
 	//vpv.services = append(vpv.services, svc)
 	vpv.AddService(cntx, svc)
 	logger.Debugw(ctx, "Added Service to VPV", log.Fields{"Num of SVCs": vpv.servicesCount.Load(), "SVC": svc})
@@ -1022,7 +1009,7 @@
 		}
 	}
 
-	//TODO: Temp Change - Need to address MAC Learning flow issues completely
+	// TODO: Temp Change - Need to address MAC Learning flow issues completely
 	if (svc.MacLearning == Learn || svc.MacLearning == ReLearn) && NonZeroMacAddress(vpv.MacAddr) {
 		svc.MacAddr = vpv.MacAddr
 	} else if vpv.servicesCount.Load() == 1 {
@@ -1032,12 +1019,12 @@
 	vpv.MacLearning = svc.MacLearning
 	vpv.PonPort = svc.PonPort
 	logger.Debugw(ctx, "Added MAC to VPV", log.Fields{"MacLearning": vpv.MacLearning, "VPV": vpv})
-	//Reconfigure Vlans based on Vlan Control type
+	// Reconfigure Vlans based on Vlan Control type
 	svc.VlanControl = vpv.VlanControl
 	if svc.McastService {
 		vpv.McastService = true
 		vpv.McastTechProfileID = svc.TechProfileID
-		//Assumption: Only one Pbit for mcast service
+		// Assumption: Only one Pbit for mcast service
 		vpv.McastPbit = svc.Pbits[0]
 		vpv.McastUsMeterID = svc.UsMeterID
 		vpv.SchedID = svc.SchedID
@@ -1046,8 +1033,8 @@
 	svc.AllowTransparent = vpv.AllowTransparent
 	svc.SVlanTpid = vpv.SVlanTpid
 
-	//Ensure configuring the mvlan profile only once
-	//One subscriber cannot have multiple mvlan profiles. Only the first configuration is valid
+	// Ensure configuring the mvlan profile only once
+	// One subscriber cannot have multiple mvlan profiles. Only the first configuration is valid
 	if svc.MvlanProfileName != "" {
 		if vpv.MvlanProfileName == "" {
 			vpv.MvlanProfileName = svc.MvlanProfileName
@@ -1059,8 +1046,8 @@
 	voltDevice, err := GetApplication().GetDeviceFromPort(vpv.Port)
 	if err != nil {
 		logger.Warnw(ctx, "Not pushing Service Flows: Error Getting Device", log.Fields{"Reason": err.Error()})
-		//statusCode, statusMessage := errorCodes.GetErrorInfo(err)
-		//TODO-COMM: 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
+		// statusCode, statusMessage := errorCodes.GetErrorInfo(err)
+		// TODO-COMM: 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 		return
 	}
 	if !svc.IsActivated {
@@ -1068,16 +1055,16 @@
 		return
 	}
 
-	//If NNI port is not mached to nb nni port
+	// If NNI port is not mached to nb nni port
 	devConfig := GetApplication().GetDeviceConfig(voltDevice.SerialNum)
 
 	if devConfig.UplinkPort != voltDevice.NniPort {
 		logger.Errorw(ctx, "NNI port mismatch", log.Fields{"NB NNI Port": devConfig.UplinkPort, "SB NNI port": voltDevice.NniPort})
 		return
 	}
-	//Push Service Flows if DHCP relay is not configured
-	//or already DHCP flows are configured for the VPV
-	//to which the serivce is associated
+	// Push Service Flows if DHCP relay is not configured
+	// or already DHCP flows are configured for the VPV
+	// to which the serivce is associated
 	if vpv.FlowsApplied {
 		if NonZeroMacAddress(vpv.MacAddr) || svc.MacLearning == MacLearningNone {
 			svc.AddHsiaFlows(cntx)
@@ -1088,7 +1075,7 @@
 		}
 	}
 
-	//Assumption: Igmp will be enabled only for one service and SubMgr ensure the same
+	// Assumption: Igmp will be enabled only for one service and SubMgr ensure the same
 	// When already the port is UP and provisioned a service without igmp, then trap flows for subsequent
 	// service with Igmp Enabled needs to be installed
 	if svc.IgmpEnabled && vpv.FlowsApplied {
@@ -1099,7 +1086,7 @@
 		}
 
 		if vpv.McastService {
-			//For McastService, send Service Activated indication once IGMP US flow is pushed
+			// For McastService, send Service Activated indication once IGMP US flow is pushed
 			vpv.RangeOnServices(cntx, PostAccessConfigSuccessInd)
 		}
 	}
@@ -1212,9 +1199,8 @@
 	return true
 }
 
-//AddTrapFlows - Adds US & DS Trap flows
+// AddTrapFlows - Adds US & DS Trap flows
 func (vpv *VoltPortVnet) AddTrapFlows(cntx context.Context) {
-
 	if !vpv.FlowsApplied || vgcRebooted {
 		if vpv.DhcpRelay {
 			if err := vpv.AddUsDhcpFlows(cntx); err != nil {
@@ -1234,7 +1220,6 @@
 				vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 			}
 			logger.Info(ctx, "ARP trap rules not added in downstream direction")
-
 		} else if vpv.PppoeIa {
 			if err := vpv.AddUsPppoeFlows(cntx); err != nil {
 				statusCode, statusMessage := errorCodes.GetErrorInfo(err)
@@ -1250,9 +1235,8 @@
 	}
 }
 
-//DelTrapFlows - Removes all US & DS DHCP, IGMP trap flows.
+// DelTrapFlows - Removes all US & DS DHCP, IGMP trap flows.
 func (vpv *VoltPortVnet) DelTrapFlows(cntx context.Context) {
-
 	// Delete HSIA & DHCP flows before deleting IGMP flows
 	if vpv.FlowsApplied || vgcRebooted {
 		if vpv.DhcpRelay {
@@ -1300,7 +1284,7 @@
 	}
 }
 
-//ClearServiceCounters - Removes all igmp counters for a service
+// 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)
@@ -1325,23 +1309,21 @@
 	if err == nil {
 		logger.Debugw(ctx, "Adding US DHCP flows", log.Fields{"Device": device})
 		if err1 := vpv.PushFlows(cntx, vd, flows); err1 != nil {
-			//push ind here ABHI
+			// push ind here ABHI
 			statusCode, statusMessage := errorCodes.GetErrorInfo(err1)
 			vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 		}
 	} else {
 		logger.Errorw(ctx, "US DHCP Flow Add Failed", log.Fields{"Reason": err.Error(), "Device": device})
-		//push ind here ABHI
+		// push ind here ABHI
 		statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
-
 	}
 	return nil
 }
 
 // AddDsDhcpFlows function pushes the DHCP flows to the VOLTHA via the controller
 func (vpv *VoltPortVnet) AddDsDhcpFlows(cntx context.Context) error {
-
 	var vd *VoltDevice
 	device := vpv.Device
 
@@ -1362,17 +1344,15 @@
 	flows, err := vpv.BuildDsDhcpFlows()
 	if err == nil {
 		if err1 := vpv.PushFlows(cntx, vd, flows); err1 != nil {
-			//push ind here and procced
+			// push ind here and procced
 			statusCode, statusMessage := errorCodes.GetErrorInfo(err1)
 			vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
-
 		}
 	} else {
 		logger.Errorw(ctx, "DS DHCP Flow Add Failed", log.Fields{"Reason": err.Error()})
-		//send ind here and proceed
+		// send ind here and proceed
 		statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
-
 	}
 	if GetApplication().GetVendorID() != Radisys {
 		vd.GlobalDhcpFlowAdded = true
@@ -1463,7 +1443,6 @@
 
 // AddUsArpFlows pushes the ARP flows to the VOLTHA via the controller
 func (vpv *VoltPortVnet) AddUsArpFlows(cntx context.Context) error {
-
 	var vd *VoltDevice
 	device := vpv.Device
 	if vd = GetApplication().GetDevice(device); vd != nil {
@@ -1553,7 +1532,6 @@
 
 	flows, err := vpv.BuildDsPppoeFlows()
 	if err == nil {
-
 		if err1 := vpv.PushFlows(cntx, vd, flows); err1 != nil {
 			return err1
 		}
@@ -1600,7 +1578,6 @@
 
 // AddIgmpFlows function pushes the IGMP flows to the VOLTHA via the controller
 func (vpv *VoltPortVnet) AddIgmpFlows(cntx context.Context) error {
-
 	if !vpv.IgmpFlowsApplied || vgcRebooted {
 		if vpv.MvlanProfileName == "" {
 			logger.Info(ctx, "Mvlan Profile not configured. Ignoring Igmp trap flow")
@@ -1644,7 +1621,6 @@
 // Write the status of the VPV to the DB once the delete is scheduled
 // for dispatch
 func (vpv *VoltPortVnet) DelIgmpFlows(cntx context.Context) error {
-
 	if vpv.IgmpFlowsApplied || vgcRebooted {
 		device, err := GetApplication().GetDeviceFromPort(vpv.Port)
 		if err != nil {
@@ -1678,7 +1654,7 @@
 	subFlow := of.NewVoltSubFlow()
 	subFlow.SetTableID(0)
 
-	if vpv.VnetType == DPU_MGMT_TRAFFIC {
+	if vpv.VnetType == DpuMgmtTraffic {
 		subFlow.SetMatchVlan(vpv.CVlan)
 		subFlow.SetMatchPbit(vpv.UsPonCTagPriority)
 		subFlow.SetPcp(vpv.UsPonSTagPriority)
@@ -1706,7 +1682,7 @@
 	vpv.services.Range(func(key, value interface{}) bool {
 		vs := value.(*VoltService)
 		var writemetadata uint64
-		if vpv.VnetType == DPU_MGMT_TRAFFIC {
+		if vpv.VnetType == DpuMgmtTraffic {
 			writemetadata = uint64(vs.SVlan)<<48 + uint64(vs.TechProfileID)<<32
 		} else {
 			writemetadata = uint64(vs.TechProfileID) << 32
@@ -1722,7 +1698,7 @@
 	if vpv.AllowTransparent {
 		allowTransparent = 1
 	}
-	if vpv.VnetType != DPU_MGMT_TRAFFIC {
+	if vpv.VnetType != DpuMgmtTraffic {
 		metadata := uint64(allowTransparent)<<56 | uint64(vpv.ONTEtherTypeClassification)<<36 | uint64(vpv.VlanControl)<<32 | uint64(vpv.UniVlan)<<16 | uint64(vpv.CVlan)
 		subFlow.SetTableMetadata(metadata)
 	}
@@ -1737,14 +1713,13 @@
 
 // BuildDsDhcpFlows to build the downstream dhcp flows
 func (vpv *VoltPortVnet) BuildDsDhcpFlows() (*of.VoltFlow, error) {
-
 	logger.Infow(ctx, "Building DS DHCP flow", log.Fields{"Port": vpv.Port, "ML": vpv.MacLearning, "Mac": vpv.MacAddr})
 	flow := &of.VoltFlow{}
 	flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
 	subFlow := of.NewVoltSubFlow()
 	subFlow.SetTableID(0)
 	// match on vlan only for fttb case
-	if vpv.VnetType == DPU_MGMT_TRAFFIC {
+	if vpv.VnetType == DpuMgmtTraffic {
 		subFlow.SetMatchVlan(vpv.SVlan)
 	}
 	subFlow.SetUdpv4Match()
@@ -1769,13 +1744,13 @@
 	if vpv.AllowTransparent {
 		allowTransparent = 1
 	}
-	if vpv.VnetType != DPU_MGMT_TRAFFIC {
+	if vpv.VnetType != DpuMgmtTraffic {
 		metadata := uint64(allowTransparent)<<56 | uint64(vpv.ONTEtherTypeClassification)<<36 | uint64(vpv.VlanControl)<<32 | uint64(vpv.UniVlan)<<16 | uint64(vpv.CVlan)
 		subFlow.SetTableMetadata(metadata)
 		subFlow.Priority = of.DhcpFlowPriority
 	}
 	subFlow.SetReportToController()
-	//| 12-bit cvlan | 4 bits empty | <32-bits uniport>| 16-bits dhcp mask or flow mask |
+	// | 12-bit cvlan | 4 bits empty | <32-bits uniport>| 16-bits dhcp mask or flow mask |
 	subFlow.Cookie = uint64(vpv.CVlan)<<52 | uint64(uniport)<<16 | of.DhcpArpFlowMask | of.DsFlowMask
 
 	flow.SubFlows[subFlow.Cookie] = subFlow
@@ -1815,7 +1790,7 @@
 	// PortName and PortID to be used for validation of port before flow pushing
 	flow.PortID = uniport
 	flow.PortName = vpv.Port
-	//subFlow.SetMeterId(vpv.UsDhcpMeterId)
+	// subFlow.SetMeterId(vpv.UsDhcpMeterId)
 	// metadata := uint64(uniport)
 	// subFlow.SetWriteMetadata(metadata)
 	allowTransparent := 0
@@ -1825,7 +1800,7 @@
 	metadata := uint64(allowTransparent)<<56 | uint64(vpv.ONTEtherTypeClassification)<<36 | uint64(vpv.VlanControl)<<32 | uint64(vpv.UniVlan)<<16 | uint64(vpv.CVlan)
 	subFlow.SetTableMetadata(metadata)
 	subFlow.SetReportToController()
-	//| 12-bit cvlan | 4 bits empty | <32-bits uniport>| 16-bits dhcp mask or flow mask |
+	// | 12-bit cvlan | 4 bits empty | <32-bits uniport>| 16-bits dhcp mask or flow mask |
 	subFlow.Cookie = uint64(vpv.CVlan)<<52 | uint64(uniport)<<16 | of.Dhcpv6FlowMask | of.UsFlowMask
 	subFlow.Priority = of.DhcpFlowPriority
 
@@ -1870,7 +1845,7 @@
 	metadata := uint64(allowTransparent)<<56 | uint64(vpv.ONTEtherTypeClassification)<<36 | uint64(vpv.VlanControl)<<32 | uint64(vpv.UniVlan)<<16 | uint64(vpv.CVlan)
 	subFlow.SetTableMetadata(metadata)
 	subFlow.SetReportToController()
-	//| 12-bit cvlan | 4 bits empty | <32-bits uniport>| 16-bits dhcp mask or flow mask |
+	// | 12-bit cvlan | 4 bits empty | <32-bits uniport>| 16-bits dhcp mask or flow mask |
 	subFlow.Cookie = uint64(vpv.CVlan)<<52 | uint64(uniport)<<16 | of.Dhcpv6FlowMask | of.DsFlowMask
 	subFlow.Priority = of.DhcpFlowPriority
 
@@ -1949,7 +1924,6 @@
 
 // BuildUsPppoeFlows to build upstream pppoe flows
 func (vpv *VoltPortVnet) BuildUsPppoeFlows() (*of.VoltFlow, error) {
-
 	flow := &of.VoltFlow{}
 	flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
 	logger.Infow(ctx, "Building US PPPoE flow", log.Fields{"Port": vpv.Port})
@@ -1984,7 +1958,7 @@
 	metadata = uint64(allowTransparent)<<56 | uint64(vpv.ONTEtherTypeClassification)<<36 | uint64(vpv.VlanControl)<<32 | uint64(vpv.UniVlan)<<16 | uint64(vpv.CVlan)
 	subFlow.SetTableMetadata(metadata)
 
-	//| 12-bit cvlan | 4 bits empty | <32-bits uniport>| 16-bits pppoe mask or flow mask |
+	// | 12-bit cvlan | 4 bits empty | <32-bits uniport>| 16-bits pppoe mask or flow mask |
 	subFlow.Cookie = uint64(vpv.CVlan)<<52 | uint64(uniport)<<16 | of.PppoeFlowMask | of.UsFlowMask
 	subFlow.Priority = of.PppoeFlowPriority
 
@@ -1995,7 +1969,6 @@
 
 // BuildDsPppoeFlows to build downstream pppoe flows
 func (vpv *VoltPortVnet) BuildDsPppoeFlows() (*of.VoltFlow, error) {
-
 	logger.Infow(ctx, "Building DS PPPoE flow", log.Fields{"Port": vpv.Port, "ML": vpv.MacLearning, "Mac": vpv.MacAddr})
 	flow := &of.VoltFlow{}
 	flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
@@ -2031,7 +2004,7 @@
 	metadata = uint64(allowTransparent)<<56 | uint64(vpv.ONTEtherTypeClassification)<<36 | uint64(vpv.VlanControl)<<32 | uint64(vpv.UniVlan)<<16 | uint64(vpv.CVlan)
 	subFlow.SetTableMetadata(metadata)
 	subFlow.SetReportToController()
-	//| 12-bit cvlan | 4 bits empty | <32-bits uniport>| 16-bits dhcp mask or flow mask |
+	// | 12-bit cvlan | 4 bits empty | <32-bits uniport>| 16-bits dhcp mask or flow mask |
 	subFlow.Cookie = uint64(vpv.CVlan)<<52 | uint64(uniport)<<16 | of.PppoeFlowMask | of.DsFlowMask
 	subFlow.Priority = of.PppoeFlowPriority
 
@@ -2085,7 +2058,7 @@
 		subFlow.SetMatchSrcMac(vpv.MacAddr)
 	}
 	logger.Infow(ctx, "Mvlan", log.Fields{"mvlan": mvlan})
-	//metadata := uint64(mvlan)
+	// metadata := uint64(mvlan)
 
 	if vpv.McastService {
 		metadata := uint64(vpv.McastUsMeterID)
@@ -2112,7 +2085,7 @@
 	subFlow.SetTableMetadata(metadata)
 	subFlow.SetIgmpMatch()
 	subFlow.SetReportToController()
-	//| 16 bits empty | <32-bits uniport>| 16-bits igmp mask or flow mask |
+	// | 16 bits empty | <32-bits uniport>| 16-bits igmp mask or flow mask |
 	subFlow.Cookie = uint64(uniport)<<16 | of.IgmpFlowMask | of.UsFlowMask
 	subFlow.Priority = of.IgmpFlowPriority
 
@@ -2130,7 +2103,7 @@
 	vpv.ForceWriteToDb(cntx)
 }
 
-//ForceWriteToDb force commit a VPV to the DB
+// ForceWriteToDb force commit a VPV to the DB
 func (vpv *VoltPortVnet) ForceWriteToDb(cntx context.Context) {
 	vpv.PendingFlowLock.RLock()
 	defer vpv.PendingFlowLock.RUnlock()
@@ -2264,7 +2237,6 @@
 		vpv.setDevice(d.Name)
 		p := d.GetPort(port)
 		if p != nil {
-
 			if vs.PonPort != 0xFF && vs.PonPort != p.PonPort {
 				logger.Errorw(ctx, "UNI port discovered on wrong PON Port. Dropping Flow Push for VPV", log.Fields{"Device": d.Name, "Port": port, "DetectedPon": p.PonPort, "ExpectedPon": vs.PonPort, "Vnet": vpv.VnetName})
 			} else {
@@ -2281,17 +2253,16 @@
 
 // DelVnetFromPort for deleting vnet from port
 func (va *VoltApplication) DelVnetFromPort(cntx context.Context, port string, vpv *VoltPortVnet) {
-
-	//Delete DHCP Session
+	// Delete DHCP Session
 	delDhcpSessions(vpv.LearntMacAddr, vpv.SVlan, vpv.CVlan, vpv.DHCPv6DUID)
 
-	//Delete PPPoE session
+	// Delete PPPoE session
 	delPppoeIaSessions(vpv.LearntMacAddr, vpv.SVlan, vpv.CVlan)
 
-	//Delete Mac from MacPortMap
+	// Delete Mac from MacPortMap
 	va.DeleteMacInPortMap(vpv.MacAddr)
 
-	//Delete VPV
+	// Delete VPV
 	vpvsIntf, ok := va.VnetsByPort.Load(port)
 	if !ok {
 		return
@@ -2349,7 +2320,6 @@
 			va.VnetsToDelete[vnet.Name] = true
 			logger.Warnw(ctx, "Vnet (restored) to be deleted", log.Fields{"Vnet": vnet.Name})
 		}
-
 	}
 }
 
@@ -2371,7 +2341,7 @@
 		return nil
 	}
 
-	//To return the matched service
+	// To return the matched service
 	var service *VoltService
 
 	// This is an access port and the port should have all the associated
@@ -2512,7 +2482,7 @@
 				return true
 			}
 
-			//Pushing ICMPv6 Flow
+			// Pushing ICMPv6 Flow
 			flow := BuildICMPv6Flow(portID, vnet)
 			err = cntlr.GetController().AddFlows(cntx, device.NniPort, device.Name, flow)
 			if err != nil {
@@ -2610,7 +2580,7 @@
 				logger.Warnw(ctx, "Skipping ICMPv6 Flow Deletion - Port Down", log.Fields{"Device": device})
 				return true
 			}
-			//Pushing ICMPv6 Flow
+			// Pushing ICMPv6 Flow
 			flow := BuildICMPv6Flow(portID, vnet)
 			flow.ForceAction = true
 			err := vnet.RemoveFlows(cntx, device, flow)
@@ -2620,7 +2590,7 @@
 			}
 			logger.Infow(ctx, "ICMPv6 Flow Delete Added to Queue", log.Fields{"flow": flow})
 
-			//Pushing ARP Flow
+			// Pushing ARP Flow
 			flow = BuildDSArpFlow(portID, vnet)
 			flow.ForceAction = true
 			err = vnet.RemoveFlows(cntx, device, flow)
@@ -2770,7 +2740,7 @@
 	return flow
 }
 
-//BuildDSArpFlow Builds DS flow for ARP
+// BuildDSArpFlow Builds DS flow for ARP
 func BuildDSArpFlow(inport uint32, vnet *VoltVnet) *of.VoltFlow {
 	logger.Infow(ctx, "Building ARP MC Flow", log.Fields{"SVlan": vnet.SVlan, "CVlan": vnet.CVlan})
 
@@ -2806,7 +2776,6 @@
 
 // setPbitRemarking to set Pbit remarking
 func (vv *VoltVnet) setPbitRemarking() uint32 {
-
 	// 	                              Remarkable
 	// 	         Remarked Pbit          Pbit
 	// |-----------------------------| |------|
@@ -2828,7 +2797,6 @@
 
 // ProcessIcmpv6McGroup to add icmpv6 multicast group
 func ProcessIcmpv6McGroup(device string, delete bool) error {
-
 	logger.Info(ctx, "Creating ICMPv6 MC Group")
 	va := GetApplication()
 	vd := va.GetDevice(device)
@@ -2859,9 +2827,8 @@
 	return err
 }
 
-//isVlanMatching - checks is vlans matches with vpv based on vlan control
+// isVlanMatching - checks is vlans matches with vpv based on vlan control
 func (vpv *VoltPortVnet) isVlanMatching(cvlan of.VlanType, svlan of.VlanType) bool {
-
 	switch vpv.VlanControl {
 	case ONUCVlanOLTSVlan,
 		OLTCVlanOLTSVlan:
@@ -2880,9 +2847,8 @@
 	return false
 }
 
-//PushFlows - Triggers flow addition after registering for flow indication event
+// PushFlows - Triggers flow addition after registering for flow indication event
 func (vpv *VoltPortVnet) PushFlows(cntx context.Context, device *VoltDevice, flow *of.VoltFlow) error {
-
 	for cookie := range flow.SubFlows {
 		cookie := strconv.FormatUint(cookie, 10)
 		fe := &FlowEvent{
@@ -2895,9 +2861,8 @@
 	return cntlr.GetController().AddFlows(cntx, vpv.Port, device.Name, flow)
 }
 
-//FlowInstallFailure - Process flow failure indication and triggers HSIA failure for all associated services
+// FlowInstallFailure - Process flow failure indication and triggers HSIA failure for all associated services
 func (vpv *VoltPortVnet) FlowInstallFailure(cookie string, errorCode uint32, errReason string) {
-
 	sendFlowFailureInd := func(key, value interface{}) bool {
 		//svc := value.(*VoltService)
 		//TODO-COMM: svc.triggerServiceFailureInd(errorCode, errReason)
@@ -2907,9 +2872,8 @@
 	vpv.services.Range(sendFlowFailureInd)
 }
 
-//RemoveFlows - Triggers flow deletion after registering for flow indication event
+// RemoveFlows - Triggers flow deletion after registering for flow indication event
 func (vpv *VoltPortVnet) RemoveFlows(cntx context.Context, device *VoltDevice, flow *of.VoltFlow) error {
-
 	vpv.PendingFlowLock.Lock()
 	defer vpv.PendingFlowLock.Unlock()
 
@@ -2927,7 +2891,7 @@
 	return cntlr.GetController().DelFlows(cntx, vpv.Port, device.Name, flow)
 }
 
-//CheckAndDeleteVpv - remove VPV from DB is there are no pending flows to be removed
+// CheckAndDeleteVpv - remove VPV from DB is there are no pending flows to be removed
 func (vpv *VoltPortVnet) CheckAndDeleteVpv(cntx context.Context) {
 	vpv.PendingFlowLock.RLock()
 	defer vpv.PendingFlowLock.RUnlock()
@@ -2941,7 +2905,7 @@
 	}
 }
 
-//FlowRemoveSuccess - Process flow success indication
+// FlowRemoveSuccess - Process flow success indication
 func (vpv *VoltPortVnet) FlowRemoveSuccess(cntx context.Context, cookie string, device string) {
 	vpv.PendingFlowLock.Lock()
 	logger.Infow(ctx, "VPV Flow Remove Success Notification", log.Fields{"Port": vpv.Port, "Cookie": cookie, "Device": device})
@@ -2952,7 +2916,7 @@
 	vpv.WriteToDb(cntx)
 }
 
-//FlowRemoveFailure - Process flow failure indication and triggers Del HSIA failure for all associated services
+// FlowRemoveFailure - Process flow failure indication and triggers Del HSIA failure for all associated services
 func (vpv *VoltPortVnet) FlowRemoveFailure(cntx context.Context, cookie string, device string, errorCode uint32, errReason string) {
 	vpv.PendingFlowLock.Lock()
 
@@ -2976,9 +2940,8 @@
 	}
 }
 
-//RemoveFlows - Triggers flow deletion after registering for flow indication event
+// RemoveFlows - Triggers flow deletion after registering for flow indication event
 func (vv *VoltVnet) RemoveFlows(cntx context.Context, device *VoltDevice, flow *of.VoltFlow) error {
-
 	vv.VnetLock.Lock()
 	defer vv.VnetLock.Unlock()
 
@@ -3004,7 +2967,7 @@
 	return cntlr.GetController().DelFlows(cntx, device.NniPort, device.Name, flow)
 }
 
-//CheckAndDeleteVnet - remove Vnet from DB is there are no pending flows to be removed
+// CheckAndDeleteVnet - remove Vnet from DB is there are no pending flows to be removed
 func (vv *VoltVnet) CheckAndDeleteVnet(cntx context.Context, device string) {
 	if !vv.DeleteInProgress {
 		return
@@ -3021,7 +2984,7 @@
 	vv.VnetPortLock.RUnlock()
 }
 
-//FlowRemoveSuccess - Process flow success indication
+// FlowRemoveSuccess - Process flow success indication
 func (vv *VoltVnet) FlowRemoveSuccess(cntx context.Context, cookie string, device string) {
 	vv.VnetLock.Lock()
 	defer vv.VnetLock.Unlock()
@@ -3042,9 +3005,8 @@
 	vv.WriteToDb(cntx)
 }
 
-//FlowRemoveFailure - Process flow failure indication
+// FlowRemoveFailure - Process flow failure indication
 func (vv *VoltVnet) FlowRemoveFailure(cntx context.Context, cookie string, device string, errorCode uint32, errReason string) {
-
 	vv.VnetLock.Lock()
 	defer vv.VnetLock.Unlock()
 
@@ -3062,11 +3024,10 @@
 	logger.Errorw(ctx, "Device Flow Remove Failure Notification for Unknown cookie", log.Fields{"Vnet": vv.Name, "Cookie": cookie, "ErrorCode": errorCode, "ErrorReason": errReason})
 }
 
-//IgmpFlowInstallFailure - Process flow failure indication and triggers HSIA failure for Igmp enabled services
+// IgmpFlowInstallFailure - Process flow failure indication and triggers HSIA failure for Igmp enabled services
 func (vpv *VoltPortVnet) IgmpFlowInstallFailure(cookie string, errorCode uint32, errReason string) {
-
-	//Note: Current implementation supports only for single service with Igmp Enabled for a subscriber
-	//When multiple Igmp-suported service enabled, comment "return false"
+	// Note: Current implementation supports only for single service with Igmp Enabled for a subscriber
+	// When multiple Igmp-suported service enabled, comment "return false"
 
 	sendFlowFailureInd := func(key, value interface{}) bool {
 		svc := value.(*VoltService)
@@ -3082,7 +3043,6 @@
 
 // GetMatchingMcastService to get matching multicast service
 func (va *VoltApplication) GetMatchingMcastService(port string, device string, cvlan of.VlanType) *VoltService {
-
 	var service *VoltService
 	dIntf, ok := va.DevicesDisc.Load(device)
 	if !ok {
@@ -3128,7 +3088,7 @@
 	return service
 }
 
-//TriggerAssociatedFlowDelete - Re-trigger delete for pending delete flows
+// TriggerAssociatedFlowDelete - Re-trigger delete for pending delete flows
 func (vv *VoltVnet) TriggerAssociatedFlowDelete(cntx context.Context, device string) bool {
 	vv.VnetLock.Lock()
 	cookieList := []uint64{}
@@ -3159,8 +3119,8 @@
 	return true
 }
 
-// JsonMarshal wrapper function for json Marshal VoltVnet
-func (vv *VoltVnet) JsonMarshal() ([]byte, error) {
+// JSONMarshal wrapper function for json Marshal VoltVnet
+func (vv *VoltVnet) JSONMarshal() ([]byte, error) {
 	return json.Marshal(VoltVnet{
 		VnetConfig: vv.VnetConfig,
 		Version:    vv.Version,
@@ -3172,8 +3132,8 @@
 	})
 }
 
-// JsonMarshal wrapper function for json Marshal VoltPortVnet
-func (vpv *VoltPortVnet) JsonMarshal() ([]byte, error) {
+// JSONMarshal wrapper function for json Marshal VoltPortVnet
+func (vpv *VoltPortVnet) JSONMarshal() ([]byte, error) {
 	return json.Marshal(VoltPortVnet{
 		Device:                     vpv.Device,
 		Port:                       vpv.Port,
