diff --git a/internal/pkg/application/igmpprofiles.go b/internal/pkg/application/igmpprofiles.go
new file mode 100644
index 0000000..b5b24d4
--- /dev/null
+++ b/internal/pkg/application/igmpprofiles.go
@@ -0,0 +1,1229 @@
+/*
+* Copyright 2022-present Open Networking Foundation
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package application
+
+import (
+	"encoding/json"
+	"errors"
+	"net"
+	"strconv"
+	"strings"
+	"sync"
+
+	cntlr "voltha-go-controller/internal/pkg/controller"
+	"voltha-go-controller/internal/pkg/types"
+	"voltha-go-controller/database"
+	"voltha-go-controller/internal/pkg/of"
+	"voltha-go-controller/internal/pkg/util"
+	"voltha-go-controller/log"
+)
+
+// ------------------------------------------------------------
+// MVLAN related implemnetation
+//
+// Each MVLAN is configured with groups of multicast IPs. The idea of
+// groups is to be able to group some multicast channels into an individual
+// PON group and have a unique multicast GEM port for that set. However, in
+// the current implementation, the concept of grouping is not fully utilized.
+
+// MvlanGroup structure
+// A set of MC IPs form a group
+
+// 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
+}
+
+// MvlanGroup identifies MC group info
+type MvlanGroup struct {
+        Name     string
+        Wildcard bool
+        McIPs    []string
+        IsStatic bool
+}
+
+// OperInProgress type
+type OperInProgress uint8
+
+const (
+        // 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
+// the MVLAN IP is not repeated within multiples groups and across
+// 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
+}
+
+// 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)
+
+        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)
+
+        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
+}
+
+// GetUsMatchVlan provides mvlan for US Match parameter
+func (mvp *MvlanProfile) GetUsMatchVlan() of.VlanType {
+        if mvp.IsPonVlanPresent {
+                return mvp.PonVlan
+        }
+        return mvp.Mvlan
+}
+
+// WriteToDb is utility to write Mvlan Profile Info to database
+func (mvp *MvlanProfile) WriteToDb() error {
+
+        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(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
+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
+}
+
+//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
+}
+
+//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
+}
+
+//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
+}
+
+//getAllChannels - Returns all channels in the Mvlan Profile
+func (mvg *MvlanGroup) getAllChannels() ([]net.IP, bool) {
+        channelList := []net.IP{}
+
+        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]))
+
+                        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
+func (mvp *MvlanProfile) SetUpdateStatus(serialNum string, status OperInProgress) {
+        if serialNum != "" {
+                mvp.DevicesList[serialNum] = status
+                return
+        }
+
+        for srNo := range mvp.DevicesList {
+                mvp.DevicesList[srNo] = status
+        }
+}
+
+//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
+}
+
+//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
+}
+
+// DelFromDb to delere mvlan from database
+func (mvp *MvlanProfile) DelFromDb() {
+        _ = db.DelMvlan(uint16(mvp.Mvlan))
+}
+
+//DelFlows - Triggers flow deletion after registering for flow indication event
+func (mvp *MvlanProfile) DelFlows(device *VoltDevice, flow *of.VoltFlow) error {
+        mvp.mvpFlowLock.Lock()
+        defer mvp.mvpFlowLock.Unlock()
+
+        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)
+
+                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(); err != nil {
+                logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
+        }
+        return cntlr.GetController().DelFlows(device.NniPort, device.Name, flow)
+}
+
+//FlowRemoveSuccess - Process flow success indication
+func (mvp *MvlanProfile) FlowRemoveSuccess(cookie string, device string) {
+        mvp.mvpFlowLock.Lock()
+        defer mvp.mvpFlowLock.Unlock()
+
+        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 err := mvp.WriteToDb(); err != nil {
+                logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
+        }
+}
+
+//FlowRemoveFailure - Process flow failure indication
+func (mvp *MvlanProfile) FlowRemoveFailure(cookie string, device string, errorCode uint32, errReason string) {
+
+        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})
+
+}
+
+// IsStaticGroup to check if group is static
+func (mvp *MvlanProfile) IsStaticGroup(groupName string) bool {
+        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
+}
+
+// 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 ""
+}
+
+// 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
+}
+
+//pushIgmpMcastFlows - Adds all IGMP related flows (generic DS flow & static group flows)
+func (mvp *MvlanProfile) pushIgmpMcastFlows(OLTSerialNum string) {
+
+        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
+        }
+
+        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)
+
+        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(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(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)
+func (mvp *MvlanProfile) removeIgmpMcastFlows(oltSerialNum string) {
+
+        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})
+
+                        // ***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(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(igd)
+                                        if ig.NumDevicesActive() == 0 {
+                                                GetApplication().DelIgmpGroup(ig)
+                                        }
+                                }
+                                return true
+                        })
+
+                        //Remove DS Igmp trap flow
+                        err := mvp.RemoveIgmpDSFlowForMvp(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(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
+
+        flowAlreadyApplied, ok := d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)]
+        if !ok || !flowAlreadyApplied {
+                flows, err := mvp.BuildIgmpDSFlows(device)
+                if err == nil {
+                        err = cntlr.GetController().AddFlows(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
+}
+
+// RemoveIgmpDSFlowForMvp to remove Igmp DS flow for mvlan.
+func (mvp *MvlanProfile) RemoveIgmpDSFlowForMvp(device string) error {
+
+        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
+
+                err = mvp.DelFlows(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
+}
+
+// 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)
+
+        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
+
+        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
+func (mvp *MvlanProfile) updateStaticGroups(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)
+
+                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(d.Name, added, true)
+                mvp.ProcessStaticGroup(d.Name, removed, false)
+                //}
+                return true
+        }
+
+        if deviceID != "" {
+                vd := GetApplication().GetDevice(deviceID)
+                updateGroups(deviceID, vd)
+        } else {
+                GetApplication().DevicesDisc.Range(updateGroups)
+        }
+}
+
+//updateDynamicGroups - Generates joins with updated sources for existing channels
+func (mvp *MvlanProfile) updateDynamicGroups(deviceID string, added []net.IP, removed []net.IP) {
+
+        //mvlan := mvp.Mvlan
+        va := GetApplication()
+
+        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(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(port, ip, incl); change {
+                                                                groupModified = true
+                                                        }
+                                                        igc.ProcessMode(port, incl)
+
+                                                        if err := igp.WriteToDb(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(); 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)
+        }
+}
+
+//GroupsUpdated - Handles removing of Igmp Groups, flows & group table entries for
+//channels removed as part of update
+func (mvp *MvlanProfile) GroupsUpdated(deviceID string) {
+
+        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 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(deviceID, channelIP)
+                                                } else {
+                                                        if (ig.IsGroupStatic) && mvp.IsStaticGroup(ig.GroupName) {
+                                                                if ig.GroupName != mvp.GetStaticGroupName(channelIP) {
+                                                                        ig.HandleGroupMigration(deviceID, channelIP)
+                                                                }
+                                                        }
+                                                        continue
+                                                }
+                                        } else {
+                                                logger.Debugw(ctx, "Channel Removed", log.Fields{"Channel": channel, "Group": grpName})
+                                                ig.DelIgmpChannel(deviceID, net.ParseIP(channel))
+                                                if ig.NumDevicesActive() == 0 {
+                                                        GetApplication().DelIgmpGroup(ig)
+                                                }
+                                        }
+                                }
+                                ig.IsGroupStatic = mvp.IsStaticGroup(ig.GroupName)
+                                if err := ig.WriteToDb(); 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()
+                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) != "")
+        }
+
+        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
+                }
+        }
+
+        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(device string, groupAddresses []net.IP, isJoin bool) {
+
+        logger.Debugw(ctx, "Received Static Group Request", log.Fields{"Device": device, "Join": isJoin, "Group Address List": groupAddresses})
+
+        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
+
+                        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(mvp.Name, groupAddr, device); ig != nil {
+                                        ig.IgmpGroupLock.Lock()
+                                        ig.AddReceiver(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(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(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(device, StaticPort, groupAddr, nil, 0xFF)
+                                        ig.IgmpGroupLock.Unlock()
+                                        ig.updateGroupName(grpName)
+                                } else {
+                                        ig.DelIgmpGroup()
+                                }
+                        } else {
+                                ig.IgmpGroupLock.Lock()
+                                ig.DelReceiver(device, StaticPort, groupAddr, nil, 0xFF)
+                                ig.IgmpGroupLock.Unlock()
+                        }
+                        if ig.NumDevicesActive() == 0 {
+                                GetApplication().DelIgmpGroup(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
+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
+}
+
+//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
+}
+
+// UpdateProfile - Updates the group & member info w.r.t the mvlan profile for the given device
+func (mvp *MvlanProfile) UpdateProfile(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()
+
+        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})
+
+                if len(addedStaticChannels) > 0 || len(removedStaticChannels) > 0 {
+                        mvp.updateStaticGroups(deviceID, []net.IP{}, removedStaticChannels)
+                }
+        }
+        mvp.GroupsUpdated(deviceID)
+        if len(addedStaticChannels) > 0 {
+                mvp.updateStaticGroups(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(deviceID, commonChannels, []net.IP{})
+                        } else {
+                                /* Dynamic group proxy modified, need to trigger membership report with new mode/src-list for existing channels */
+                                mvp.updateDynamicGroups(deviceID, commonChannels, []net.IP{})
+                        }
+                }
+        }
+
+        mvp.SetUpdateStatus(serialNo, NoOp)
+
+        if deviceID == "" || !mvp.isUpdateInProgress() {
+                mvp.oldGroups = nil
+        }
+        if err := mvp.WriteToDb(); 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
+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.Mode != newProxy.Mode {
+                return true
+        }
+
+        oldSrcLst := oldProxy.SourceList
+        newSrcLst := newProxy.SourceList
+        oLen := len(oldSrcLst)
+        nLen := len(newSrcLst)
+        if oLen != nLen {
+                return true
+        }
+
+        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
+                }
+        }
+
+        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
+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
+                })
+        }
+}
+
+//TriggerAssociatedFlowDelete - Re-trigger delete for pending delete flows
+func (mvp *MvlanProfile) TriggerAssociatedFlowDelete(device string) bool {
+        mvp.mvpFlowLock.Lock()
+
+        cookieList := []uint64{}
+        flowMap := mvp.PendingDeleteFlow[device]
+
+        for cookie := range flowMap {
+                cookieList = append(cookieList, convertToUInt64(cookie))
+        }
+        mvp.mvpFlowLock.Unlock()
+
+        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(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,
+        })
+}
+
+// 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
+}
+
+// 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
+}
+
+// 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
+}
+
+func newIgmpProfile(igmpProfileConfig *common.IGMPConfig) *IgmpProfile {
+        var igmpProfile IgmpProfile
+        igmpProfile.ProfileID = igmpProfileConfig.ProfileID
+        igmpProfile.UnsolicitedTimeOut = uint32(igmpProfileConfig.UnsolicitedTimeOut)
+        igmpProfile.MaxResp = uint32(igmpProfileConfig.MaxResp)
+
+        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
+
+        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)
+
+        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
+        }
+}
+
+// WriteToDb is utility to write Igmp Config Info to database
+func (igmpProfile *IgmpProfile) WriteToDb() error {
+        igmpProfile.Version = database.PresentVersionMap[database.IgmpProfPath]
+        b, err := json.Marshal(igmpProfile)
+        if err != nil {
+                return err
+        }
+        if err1 := db.PutIgmpProfile(igmpProfile.ProfileID, string(b)); err1 != nil {
+                return err1
+        }
+        return nil
+}
