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++
+	}
 }
-
