net config restinterface along with mvlan delete rest api

Change-Id: I4d8f5829d4e8b08be7981716cb3cde26cc5a507c
diff --git a/database/common.go b/database/common.go
index ea8f3b6..6d7b4a7 100644
--- a/database/common.go
+++ b/database/common.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.
-*/
+ */
 // This implementation of database assumes that it is working for
 // Open ONU adapter. Thus, it assumes some base path for all the
 // database operations. For all database operations, the key passed is
@@ -64,6 +64,7 @@
 	SubAlarmDataPath       string = DevicePath + "sub-alarm-data/"
 	ServicesMigrateReqPath string = DevicePath + "migrateServicesReq/"
 	OltFlowServicePath     string = "olt-flow-service/"
+	DeviceConfigPath       string = "device-config/"
 )
 
 //PresentVersionMap - map of present version for all database tables
@@ -99,6 +100,7 @@
 	SubAlarmDataPath:       "v1",
 	ServicesMigrateReqPath: "v1",
 	OltFlowServicePath:     "v1",
+	DeviceConfigPath:       "v1",
 }
 
 //PreviousVersionMap - map of previous version for all database tables
@@ -134,6 +136,7 @@
 	SubAlarmDataPath:       "v1",
 	ServicesMigrateReqPath: "v1",
 	OltFlowServicePath:     "v1",
+	DeviceConfigPath:       "v1",
 }
 
 //DBVersionMap - Version of tables present in DB
diff --git a/database/database.go b/database/database.go
index cf673eb..75f4802 100644
--- a/database/database.go
+++ b/database/database.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.
-*/
+ */
 // This implementation of database assumes that it is working for
 // Open ONU adapter. Thus, it assumes some base path for all the
 // database operations. For all database operations, the key passed is
@@ -22,14 +22,16 @@
 import (
 	"context"
 	"errors"
+	"fmt"
 	"net"
 	"strconv"
 	"time"
-	"fmt"
 
+	"voltha-go-controller/internal/pkg/errorcodes"
 	"voltha-go-controller/internal/pkg/of"
-	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
 	"voltha-go-controller/log"
+
+	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
 )
 
 var logger log.CLogger
@@ -39,7 +41,7 @@
 	storeType string
 	address   string
 	//timeout   uint32
-	kvc       kvstore.Client
+	kvc kvstore.Client
 }
 
 // Initialize the database module. The database module runs as a singleton
@@ -494,7 +496,7 @@
 // GetHealth to get health info
 func (db *Database) GetHealth(ctx context.Context) (string, error) {
 	key := GetKeyPath(HealthPath)
-	return db.Get(ctx,key)
+	return db.Get(ctx, key)
 }
 
 // PutHealth to add health info
@@ -741,6 +743,23 @@
 	}
 }
 
+// GetServices to get multiple services info
+func (db *Database) GetDeviceConfig(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(DeviceConfigPath)
+	return db.List(ctx, key)
+}
+
+// PutSBDeviceConfig to add device info
+func (db *Database) PutDeviceConfig(ctx context.Context, serialNum string, value string) error {
+	key := GetKeyPath(DeviceConfigPath) + serialNum
+
+	if err := db.kvc.Put(ctx, key, value); err != nil {
+		logger.Warnw(ctx, "Put Device Config failed", log.Fields{"key": key})
+		return errorcodes.ErrFailedToUpdateDB
+	}
+	return nil
+}
+
 // DelNbDevicePort to delete device port
 func (db *Database) DelNbDevicePort(ctx context.Context, device string, ponPortID uint32) {
 	key := GetKeyPath(NbDevicePath) + device + "/pon-port/" + fmt.Sprintf("%v", ponPortID)
@@ -1059,10 +1078,10 @@
 	return db.Get(ctx, key)
 }
 func init() {
-        // Setup this package so that it's log level can be modified at run time
-        var err error
-        logger, err = log.AddPackageWithDefaultParam()
-        if err != nil {
-                panic(err)
-        }
+	// Setup this package so that it's log level can be modified at run time
+	var err error
+	logger, err = log.AddPackageWithDefaultParam()
+	if err != nil {
+		panic(err)
+	}
 }
diff --git a/database/dbintf.go b/database/dbintf.go
index 5de5761..6100d35 100644
--- a/database/dbintf.go
+++ b/database/dbintf.go
@@ -11,15 +11,16 @@
 * 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 database
 
 import (
-	"net"
 	"context"
+	"net"
 
 	"voltha-go-controller/internal/pkg/of"
+
 	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
 )
 
@@ -115,6 +116,8 @@
 	GetAllPonChannelCounters(ctx context.Context, device string, ponID string) (map[string]*kvstore.KVPair, error)
 	GetPonChannelCounter(ctx context.Context, device string, ponID string, channel string) (string, error)
 	PutNbDevicePort(ctx context.Context, device string, ponPortID uint32, value string)
+	GetDeviceConfig(ctx context.Context) (map[string]*kvstore.KVPair, error)
+	PutDeviceConfig(ctx context.Context, serialNum string, value string) error
 	PutPonChannelCounter(ctx context.Context, device string, ponID string, channel string, value string) error
 	DelPonChannelCounter(ctx context.Context, device string, ponID string, channel string) error
 	DelAllPONCounters(ctx context.Context, device string) error
diff --git a/internal/pkg/application/application.go b/internal/pkg/application/application.go
index 74b72f8..1f31149 100644
--- a/internal/pkg/application/application.go
+++ b/internal/pkg/application/application.go
@@ -30,14 +30,14 @@
 	"github.com/google/gopacket"
 	"github.com/google/gopacket/layers"
 
+	"voltha-go-controller/database"
 	"voltha-go-controller/internal/pkg/controller"
 	cntlr "voltha-go-controller/internal/pkg/controller"
-	"voltha-go-controller/database"
+	errorCodes "voltha-go-controller/internal/pkg/errorcodes"
 	"voltha-go-controller/internal/pkg/intf"
 	"voltha-go-controller/internal/pkg/of"
 	"voltha-go-controller/internal/pkg/tasks"
 	"voltha-go-controller/internal/pkg/util"
-	errorCodes "voltha-go-controller/internal/pkg/errorcodes"
 	"voltha-go-controller/log"
 )
 
@@ -364,7 +364,7 @@
 		port := key.(string)
 		vp := value.(*VoltPort)
 
-		logger.Infow(ctx, "NNI Discovered. Sending Port UP Ind for UNI", log.Fields{"Port" : port})
+		logger.Infow(ctx, "NNI Discovered. Sending Port UP Ind for UNI", log.Fields{"Port": port})
 		//Ignore if UNI port is not UP
 		if vp.State != PortStateUp {
 			return true
@@ -440,16 +440,24 @@
 	macPortLock sync.RWMutex
 	macPortMap  map[string]string
 
-	IgmpPendingPool map[string]map[*IgmpGroup]bool //[grpkey, map[groupObj]bool]  //mvlan_grpName/IP
-	PendingPoolLock sync.RWMutex
+	IgmpPendingPool       map[string]map[*IgmpGroup]bool //[grpkey, map[groupObj]bool]  //mvlan_grpName/IP
+	PendingPoolLock       sync.RWMutex
+	VnetsToDelete         map[string]bool
+	ServicesToDelete      map[string]bool
+	VoltPortVnetsToDelete map[*VoltPortVnet]bool
+	PortAlarmProfileCache map[string]map[string]int // [portAlarmID][ThresholdLevelString]ThresholdLevel
+	vendorID              string
+	OltFlowServiceConfig  OltFlowService
+	DevicesConfig         sync.Map //[serialNumber]*DeviceConfig
+}
 
-	VnetsToDelete             map[string]bool
-	ServicesToDelete          map[string]bool
-	VoltPortVnetsToDelete     map[*VoltPortVnet]bool
-	PortAlarmProfileCache     map[string]map[string]int // [portAlarmID][ThresholdLevelString]ThresholdLevel
-	vendorID                  string
-	OltFlowServiceConfig      OltFlowService
-	DevicesConfig             sync.Map
+type DeviceConfig struct {
+	SerialNumber       string `json:"id"`
+	HardwareIdentifier string `json:"hardwareIdentifier"`
+	IPAddress          net.IP `json:"ipAddress"`
+	UplinkPort         int    `json:"uplinkPort"`
+	NasID              string `json:"nasId"`
+	NniDhcpTrapVid     int    `json:"nniDhcpTrapVid"`
 }
 
 // PonPortCfg contains NB port config and activeIGMPChannels count
@@ -526,6 +534,79 @@
 	return ponPort
 }
 
+// RestoreDeviceConfigFromDb to restore vnet from port
+func (va *VoltApplication) RestoreDeviceConfigFromDb(cntx context.Context) {
+	// VNETS must be learnt first
+	dConfig, _ := db.GetDeviceConfig(cntx)
+	for _, device := range dConfig {
+		b, ok := device.Value.([]byte)
+		if !ok {
+			logger.Warn(ctx, "The value type is not []byte")
+			continue
+		}
+		devConfig := DeviceConfig{}
+		err := json.Unmarshal(b, &devConfig)
+		if err != nil {
+			logger.Warn(ctx, "Unmarshal of device configuration failed")
+			continue
+		}
+		logger.Debugw(ctx, "Retrieved device config", log.Fields{"Device Config": devConfig})
+		if err := va.AddDeviceConfig(cntx, devConfig.SerialNumber, devConfig.HardwareIdentifier, devConfig.NasID, devConfig.IPAddress, devConfig.UplinkPort, devConfig.NniDhcpTrapVid); err != nil {
+			logger.Warnw(ctx, "Add device config failed", log.Fields{"DeviceConfig": devConfig, "Error": err})
+		}
+
+	}
+}
+
+// WriteDeviceConfigToDb writes sb device config to kv store
+func (dc *DeviceConfig) WriteDeviceConfigToDb(cntx context.Context, serialNum string, deviceConfig *DeviceConfig) error {
+	b, err := json.Marshal(deviceConfig)
+	if err != nil {
+		logger.Errorw(ctx, "deviceConfig-marshal-failed", log.Fields{"err": err})
+		return err
+	}
+	dberr := db.PutDeviceConfig(cntx, serialNum, string(b))
+	if dberr != nil {
+		logger.Errorw(ctx, "update device config failed", log.Fields{"err": err})
+		return dberr
+	}
+	return nil
+}
+
+func (va *VoltApplication) AddDeviceConfig(cntx context.Context, serialNum, hardwareIdentifier, nasID string, ipAddress net.IP, uplinkPort, nniDhcpTrapId int) error {
+	var dc *DeviceConfig
+
+	d := va.GetDeviceConfig(serialNum)
+	if d == nil {
+		deviceConfig := &DeviceConfig{
+			SerialNumber:       serialNum,
+			HardwareIdentifier: hardwareIdentifier,
+			NasID:              nasID,
+			UplinkPort:         uplinkPort,
+			IPAddress:          ipAddress,
+			NniDhcpTrapVid:     nniDhcpTrapId,
+		}
+		va.DevicesConfig.Store(serialNum, deviceConfig)
+		err := dc.WriteDeviceConfigToDb(cntx, serialNum, deviceConfig)
+		if err != nil {
+			logger.Errorw(ctx, "DB update for device config failed", log.Fields{"err": err})
+			return err
+		}
+	} else {
+		logger.Errorw(ctx, "Device config already exist", log.Fields{"DeviceID": serialNum})
+		return errors.New("Device config already exist")
+	}
+	return nil
+}
+
+// GetDeviceConfig to get a device config.
+func (va *VoltApplication) GetDeviceConfig(serNum string) *DeviceConfig {
+	if d, ok := va.DevicesConfig.Load(serNum); ok {
+		return d.(*DeviceConfig)
+	}
+	return nil
+}
+
 // UpdatePortToNbDevice Adds pon port to NB Device and DB
 func (nbd *NbDevice) UpdatePortToNbDevice(cntx context.Context, portID, allowedChannels uint32, enableMulticastKPI bool, portAlarmProfileID string) *PonPortCfg {
 
@@ -704,6 +785,8 @@
 	va.RestoreUpgradeStatus(cntx)
 	logger.Info(ctx, "Reading OltFlowService from DB")
 	va.RestoreOltFlowService(cntx)
+	logger.Info(ctx, "Reading device config from DB")
+	va.RestoreDeviceConfigFromDb(cntx)
 	logger.Info(ctx, "Reconciled from DB")
 }
 
@@ -842,8 +925,8 @@
 		}
 		// if RemoveFlowsOnDisable is flase, then flows will be existing till port delete. Remove the flows now
 		if !va.OltFlowServiceConfig.RemoveFlowsOnDisable {
-		        vpvs, ok := va.VnetsByPort.Load(port)
-		        if !ok || nil == vpvs || len(vpvs.([]*VoltPortVnet)) == 0 {
+			vpvs, ok := va.VnetsByPort.Load(port)
+			if !ok || nil == vpvs || len(vpvs.([]*VoltPortVnet)) == 0 {
 				logger.Infow(ctx, "No VNETs on port", log.Fields{"Device": device, "Port": port})
 			} else {
 				for _, vpv := range vpvs.([]*VoltPortVnet) {
@@ -1311,14 +1394,6 @@
 		return
 	}
 
-/*
-	if p.Type != VoltPortTypeNni {
-		// Process port up indication
-		indTask := cntlr.NewAddPortInd(p.Name, msgbus.PortUp, d.SerialNum, true, getServiceList(port))
-		cntlr.GetController().PostIndication(device, indTask)
-	}
-*/
-
 	for _, vpv := range vpvs.([]*VoltPortVnet) {
 		vpv.VpvLock.Lock()
 		//If no service is activated drop the portUpInd
@@ -1424,13 +1499,7 @@
 		//msgbus.ProcessPortInd(msgbus.PortDown, d.SerialNum, p.Name, false, getServiceList(port))
 		return
 	}
-/*
-	if p.Type != VoltPortTypeNni {
-		// Process port down indication
-		indTask := cntlr.NewAddPortInd(p.Name, msgbus.PortDown, d.SerialNum, true, getServiceList(port))
-		cntlr.GetController().PostIndication(device, indTask)
-	}
-*/
+
 	for _, vpv := range vpvs.([]*VoltPortVnet) {
 		vpv.VpvLock.Lock()
 		vpv.PortDownInd(cntx, device, port, false)
@@ -1670,46 +1739,6 @@
 	cookie := subFlow.Cookie
 	uniPort := cookie >> 16 & 0xFFFFFFFF
 	logger.Errorw(ctx, "Flow Failure Notification", log.Fields{"uniPort": uniPort, "Cookie": cookie})
-/*
-	device := flowStatus.Device
-	priority := subFlow.Priority
-	isIgmp := false
-	var devSerialNum string
-	var service *VoltService
-
-	if subFlow.Match.L4Protocol == of.IPProtocolIgmp {
-		isIgmp = true
-	} else if priority != of.HsiaFlowPriority {
-		logger.Info(ctx, "Not HSIA flow, ignoring the failure notification")
-		return
-	}
-
-	cookie := subFlow.Cookie
-	pbit := subFlow.Pbits
-	uniPort := cookie >> 16 & 0xFFFFFFFF
-	portName, _ := GetApplication().GetPortName(uint32(uniPort))
-	portState := msgbus.PortDown
-	logger.Errorw(ctx, "Construct Flow Failure Notification", log.Fields{"uniPort": uniPort, "Cookie": cookie, "Pbit": pbit, "isIgmp": isIgmp})
-
-	if isIgmp {
-		cvlan := subFlow.TableMetadata & 0xFFFF
-		service = GetApplication().GetMatchingMcastService(portName, device, of.VlanType(cvlan))
-	} else {
-		service = GetApplication().GetServiceNameFromCookie(cookie, portName, uint8(pbit), device, subFlow.TableMetadata)
-	}
-	var trigger infra.Reason
-	if nil != service {
-		logger.Errorw(ctx, "Sending Flow Failure Notification", log.Fields{"uniPort": uniPort, "Cookie": cookie, "Pbit": pbit, "Service": service.Name, "ErrorCode": flowStatus.Status})
-		if vd := GetApplication().GetDevice(device); vd != nil {
-			devSerialNum = vd.SerialNum
-			if portSt, _ := GetApplication().GetPortState(service.Port); portSt == PortStateUp {
-				portState = msgbus.PortUp
-			}
-			trigger = service.getSrvDeactTrigger(vd, portState)
-		}
-		msgbus.PostAccessConfigInd(msgbus.Failed, devSerialNum, msgbus.HSIA, service.Name, int(flowStatus.Status), subFlow.ErrorReason, trigger, portState)
-	}
-*/
 }
 
 //UpdateMvlanProfilesForDevice to update mvlan profile for device
@@ -2042,25 +2071,6 @@
 				vs.DelHsiaFlows(cntx)
 				if vs.ForceDelete {
 					vs.DelFromDb(cntx)
-					/*
-					portState := msgbus.PortDown
-					if d, err := va.GetDeviceFromPort(vs.Port); d != nil {
-
-						if portSt, _ := GetApplication().GetPortState(vs.Port); portSt == PortStateUp {
-							portState = msgbus.PortUp
-						}
-						indTask := cntlr.NewAddServiceIndTask(vs.Name, d.SerialNum, msgbus.DelHSIA, msgbus.Success, "", portState, infra.DelHSIAFromNB)
-						cntlr.GetController().PostIndication(d.Name, indTask)
-					} else {
-						// Port Not found can occur during ONU movement. However, port delete had already handled flow deletion,
-						// hence indication can be sent immediately
-						var devSrNo string
-						logger.Errorw(ctx, "Device/Port not found. Send indication directly", log.Fields{"serviceName": vs.Name, "error": err})
-						if vd := va.GetDevice(vs.Device); vd != nil {
-							devSrNo = vd.SerialNum
-						}
-						msgbus.PostAccessConfigInd(msgbus.Success, devSrNo, msgbus.DelHSIA, vs.Name, 0, "", infra.DelHSIAFromNB, portState)
-					}*/
 				}
 			}
 		} else {
@@ -2100,13 +2110,13 @@
 }
 
 type OltFlowService struct {
-        EnableDhcpOnNni      bool `json:"enableDhcpOnNni"`
-        DefaultTechProfileId int  `json:"defaultTechProfileId"`
-        EnableIgmpOnNni      bool `json:"enableIgmpOnNni"`
-        EnableEapol          bool `json:"enableEapol"`
-        EnableDhcpV6         bool `json:"enableDhcpV6"`
-        EnableDhcpV4         bool `json:"enableDhcpV4"`
-        RemoveFlowsOnDisable bool `json:"removeFlowsOnDisable"`
+	EnableDhcpOnNni      bool `json:"enableDhcpOnNni"`
+	DefaultTechProfileId int  `json:"defaultTechProfileId"`
+	EnableIgmpOnNni      bool `json:"enableIgmpOnNni"`
+	EnableEapol          bool `json:"enableEapol"`
+	EnableDhcpV6         bool `json:"enableDhcpV6"`
+	EnableDhcpV4         bool `json:"enableDhcpV4"`
+	RemoveFlowsOnDisable bool `json:"removeFlowsOnDisable"`
 }
 
 func (va *VoltApplication) UpdateOltFlowService(cntx context.Context, oltFlowService OltFlowService) {
@@ -2119,6 +2129,7 @@
 	}
 	_ = db.PutOltFlowService(cntx, string(b))
 }
+
 // RestoreOltFlowService to read from the DB and restore olt flow service config
 func (va *VoltApplication) RestoreOltFlowService(cntx context.Context) {
 	oltflowService, err := db.GetOltFlowService(cntx)
@@ -2134,26 +2145,17 @@
 	logger.Infow(ctx, "updated OltFlowServiceConfig from DB", log.Fields{"OltFlowServiceConfig": va.OltFlowServiceConfig})
 }
 
-type DeviceConfig struct {
-	SerialNumber       string
-	UplinkPort         int
-	HardwareIdentifier string
-	IPAddress          net.IP
-	NasID              string
-	NniDhcpTrapVid     int
-}
-
 func (va *VoltApplication) UpdateDeviceConfig(cntx context.Context, sn, mac, nasID string, port, dhcpVid int, ip net.IP) {
 	if d, ok := va.DevicesConfig.Load(sn); ok {
 		logger.Infow(ctx, "Device configuration already exists", log.Fields{"DeviceInfo": d})
 	}
-	d := DeviceConfig {
-		SerialNumber       : sn,
-		UplinkPort         : port,
-		HardwareIdentifier : mac,
-		IPAddress          : ip,
-		NasID              : nasID,
-		NniDhcpTrapVid     : dhcpVid,
+	d := DeviceConfig{
+		SerialNumber:       sn,
+		UplinkPort:         port,
+		HardwareIdentifier: mac,
+		IPAddress:          ip,
+		NasID:              nasID,
+		NniDhcpTrapVid:     dhcpVid,
 	}
 	logger.Infow(ctx, "Added OLT configurations", log.Fields{"DeviceInfo": d})
 	va.DevicesConfig.Store(sn, d)
diff --git a/internal/pkg/application/igmp.go b/internal/pkg/application/igmp.go
index a63370d..91afdf8 100644
--- a/internal/pkg/application/igmp.go
+++ b/internal/pkg/application/igmp.go
@@ -11,7 +11,7 @@
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
-*/
+ */
 
 package application
 
@@ -21,16 +21,16 @@
 	"errors"
 	"net"
 	"reflect"
-	"voltha-go-controller/internal/pkg/types"
 	"strings"
 	"sync"
 	"time"
+	common "voltha-go-controller/internal/pkg/types"
 
 	"github.com/google/gopacket"
 	"github.com/google/gopacket/layers"
 
-	cntlr "voltha-go-controller/internal/pkg/controller"
 	"voltha-go-controller/database"
+	cntlr "voltha-go-controller/internal/pkg/controller"
 	"voltha-go-controller/internal/pkg/of"
 	"voltha-go-controller/log"
 )
@@ -865,7 +865,7 @@
 			vp := vd.GetPort(port)
 			if vp == nil || vp.State != PortStateUp {
 				logger.Warnw(ctx, "Join received from a Port that is DOWN or not present",
-						log.Fields{"Port": port})
+					log.Fields{"Port": port})
 				ig.IgmpGroupLock.Unlock()
 				return
 			}
@@ -882,7 +882,7 @@
 				vp := vd.GetPort(port)
 				if vp == nil || vp.State != PortStateUp {
 					logger.Warnw(ctx, "Join received from a Port that is DOWN or not present",
-							log.Fields{"Port": port})
+						log.Fields{"Port": port})
 					ig.IgmpGroupLock.Unlock()
 					return
 				}
@@ -1015,7 +1015,7 @@
 					vp := vd.GetPort(port)
 					if vp == nil || vp.State != PortStateUp {
 						logger.Warnw(ctx, "Join received from a Port that is DOWN or not present",
-								log.Fields{"Port": port})
+							log.Fields{"Port": port})
 						ig.IgmpGroupLock.Unlock()
 						return
 					}
@@ -1033,7 +1033,7 @@
 						vp := vd.GetPort(port)
 						if vp == nil || vp.State != PortStateUp {
 							logger.Warnw(ctx, "Join received from a Port that is DOWN or not present",
-									log.Fields{"Port": port})
+								log.Fields{"Port": port})
 							ig.IgmpGroupLock.Unlock()
 							return
 						}
@@ -1678,23 +1678,48 @@
 	va.IgmpProfilesByName.Delete(name)
 }
 
-//DelIgmpProfile for addition of IGMP Profile
-func (va *VoltApplication) DelIgmpProfile(cntx context.Context, igmpProfileConfig *common.IGMPConfig) error {
+// TODO - DelIgmpProfile for deleting IGMP Profile based on profile Id
+// func (va *VoltApplication) DelIgmpProfile(cntx context.Context, igmpProfileConfig *common.IGMPConfig) error {
+// 	// Deletion of default igmp profile is blocked from submgr. Keeping additional check for safety.
+// 	if igmpProfileConfig.ProfileID == DefaultIgmpProfID {
+// 		logger.Info(ctx, "Resetting default IGMP profile")
+// 		va.resetIgmpProfileToDefault(cntx)
+// 		return nil
+// 	}
+// 	igmpProfile := va.checkIgmpProfileMap(igmpProfileConfig.ProfileID)
+// 	if igmpProfile == nil {
+// 		logger.Warnw(ctx, "Igmp Profile not found. Unable to delete", log.Fields{"Profile ID": igmpProfileConfig.ProfileID})
+// 		return nil
+// 	}
+
+// 	va.deleteIgmpProfileMap(igmpProfileConfig.ProfileID)
+
+// 	_ = db.DelIgmpProfile(cntx, igmpProfileConfig.ProfileID)
+
+// 	return nil
+// }
+
+// DelIgmpProfile for deleting IGMP Profile based on profile Id
+func (va *VoltApplication) DelIgmpProfile(cntx context.Context, profileID string) error {
 	// Deletion of default igmp profile is blocked from submgr. Keeping additional check for safety.
-	if igmpProfileConfig.ProfileID == DefaultIgmpProfID {
+	if profileID == DefaultIgmpProfID {
 		logger.Info(ctx, "Resetting default IGMP profile")
 		va.resetIgmpProfileToDefault(cntx)
 		return nil
 	}
-	igmpProfile := va.checkIgmpProfileMap(igmpProfileConfig.ProfileID)
+	igmpProfile := va.checkIgmpProfileMap(profileID)
 	if igmpProfile == nil {
-		logger.Warnw(ctx, "Igmp Profile not found. Unable to delete", log.Fields{"Profile ID": igmpProfileConfig.ProfileID})
+		logger.Warnw(ctx, "Igmp Profile not found. Unable to delete", log.Fields{"Profile ID": profileID})
 		return nil
 	}
 
-	va.deleteIgmpProfileMap(igmpProfileConfig.ProfileID)
+	va.deleteIgmpProfileMap(profileID)
 
-	_ = db.DelIgmpProfile(cntx, igmpProfileConfig.ProfileID)
+	err := db.DelIgmpProfile(cntx, profileID)
+	if err != nil {
+		logger.Errorw(ctx, "Failed to delete Igmp profile from DB", log.Fields{"Error": err})
+		return err
+	}
 
 	return nil
 }
diff --git a/internal/pkg/application/vnets.go b/internal/pkg/application/vnets.go
index 1313490..a95104c 100644
--- a/internal/pkg/application/vnets.go
+++ b/internal/pkg/application/vnets.go
@@ -16,25 +16,27 @@
 package application
 
 import (
+	"context"
 	"encoding/json"
 	"errors"
-	"context"
 	"net"
-	infraerrorCodes "voltha-go-controller/internal/pkg/errorcodes"
 	"strconv"
 	"sync"
 	"time"
 
+	//errorCodes "voltha-go-controller/internal/pkg/errorcodes"
+
 	"github.com/google/gopacket"
 	"github.com/google/gopacket/layers"
 	"go.uber.org/atomic"
 
+	"voltha-go-controller/database"
 	"voltha-go-controller/internal/pkg/controller"
 	cntlr "voltha-go-controller/internal/pkg/controller"
-	"voltha-go-controller/database"
+
+	errorCodes "voltha-go-controller/internal/pkg/errorcodes"
 	"voltha-go-controller/internal/pkg/of"
 	"voltha-go-controller/internal/pkg/util"
-	errorCodes "voltha-go-controller/internal/pkg/errorcodes"
 	"voltha-go-controller/log"
 )
 
@@ -223,7 +225,7 @@
 	vv.Version = database.PresentVersionMap[database.VnetPath]
 	logger.Debugw(ctx, "Updating VNET....", log.Fields{"vnet": vv})
 	if b, err := json.Marshal(vv); err == nil {
-		if err:= db.PutVnet(cntx, vv.Name, string(b)); err != nil {
+		if err := db.PutVnet(cntx, vv.Name, string(b)); err != nil {
 			logger.Warnw(ctx, "Add Vnet to DB failed", log.Fields{"vnet name": vv.Name, "Error": err})
 		}
 	}
@@ -652,7 +654,7 @@
 	// If the only Igmp Enabled service is removed, remove the Igmp trap flow along with it
 	if service.IgmpEnabled {
 		if err := vpv.DelIgmpFlows(cntx); err != nil {
-			statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+			statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 			vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 		}
 
@@ -775,8 +777,18 @@
 		return
 	}
 
-	if vp := device.GetPort(port); vp != nil {
+	if nniPort := device.GetPort(nni); nniPort != nil {
+		//If NNI port is not mached to nb nni port dont send flows
+		devConfig := GetApplication().GetDeviceConfig(device.SerialNum)
+		if devConfig != nil {
+			if devConfig.UplinkPort != int(nniPort.ID) {
+				logger.Errorw(ctx, "NNI port not configured from NB, not pushing flows", log.Fields{"NNI Port": devConfig.UplinkPort, "NB NNI port": nniPort.ID})
+				return
+			}
+		}
+	}
 
+	if vp := device.GetPort(port); vp != nil {
 		if vpv.PonPort != 0xFF && vpv.PonPort != vp.PonPort {
 			logger.Errorw(ctx, "UNI port discovered on wrong PON Port. Dropping Flow Config for VPV", log.Fields{"Device": device.Name, "Port": port, "DetectedPon": vp.PonPort, "ExpectedPon": vpv.PonPort, "Vnet": vpv.VnetName})
 			return
@@ -835,7 +847,7 @@
 		logger.Infow(ctx, "Port Up - IGMP Flows", log.Fields{"Device": device.Name, "Port": port})
 		vpv.RangeOnServices(cntx, AddSvcUsMeterToDevice)
 		if err := vpv.AddIgmpFlows(cntx); err != nil {
-			statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+			statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 			vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 		}
 
@@ -916,7 +928,7 @@
 	_, err := GetApplication().GetDeviceFromPort(vpv.Port)
 	if err != nil {
 		logger.Warnw(ctx, "Not pushing Service Flows: Error Getting Device", log.Fields{"Reason": err.Error()})
-		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+		statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 		return
 	}
@@ -1072,10 +1084,10 @@
 		}
 	}
 
-	_, err := GetApplication().GetDeviceFromPort(vpv.Port)
+	voltDevice, err := GetApplication().GetDeviceFromPort(vpv.Port)
 	if err != nil {
 		logger.Warnw(ctx, "Not pushing Service Flows: Error Getting Device", log.Fields{"Reason": err.Error()})
-		//statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+		//statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 		//TODO-COMM: 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 		return
 	}
@@ -1083,6 +1095,14 @@
 		logger.Warn(ctx, "Not pushing Service Flows: Service Not activated")
 		return
 	}
+
+	//If NNI port is not mached to nb nni port
+	devConfig := GetApplication().GetDeviceConfig(voltDevice.SerialNum)
+
+	if strconv.Itoa(devConfig.UplinkPort) != voltDevice.NniPort {
+		logger.Errorw(ctx, "NNI port mismatch", log.Fields{"NNI Port": devConfig.UplinkPort, "NB NNI port": voltDevice.NniPort})
+		return
+	}
 	//Push Service Flows if DHCP relay is not configured
 	//or already DHCP flows are configured for the VPV
 	//to which the serivce is associated
@@ -1090,7 +1110,7 @@
 		if NonZeroMacAddress(vpv.MacAddr) || svc.MacLearning == MacLearningNone {
 			svc.AddHsiaFlows(cntx)
 		} else {
-			if err:= svc.AddUsHsiaFlows(cntx); err != nil {
+			if err := svc.AddUsHsiaFlows(cntx); err != nil {
 				logger.Warnw(ctx, "Add US hsia flow failed", log.Fields{"service": svc.Name, "Error": err})
 			}
 		}
@@ -1102,7 +1122,7 @@
 	if svc.IgmpEnabled && vpv.FlowsApplied {
 		logger.Infow(ctx, "Add Service - IGMP Flows", log.Fields{"Device": vpv.Device, "Port": vpv.Port})
 		if err := vpv.AddIgmpFlows(cntx); err != nil {
-			statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+			statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 			vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 		}
 
@@ -1149,7 +1169,7 @@
 // AddUsHsiaFlows to add upstream hsia flows
 func AddUsHsiaFlows(cntx context.Context, key, value interface{}) bool {
 	svc := value.(*VoltService)
-	if err:= svc.AddUsHsiaFlows(cntx); err != nil {
+	if err := svc.AddUsHsiaFlows(cntx); err != nil {
 		logger.Warnw(ctx, "Add US hsia flow failed", log.Fields{"service": svc.Name, "Error": err})
 	}
 	return true
@@ -1158,7 +1178,7 @@
 // AddDsHsiaFlows to add downstream hsia flows
 func AddDsHsiaFlows(cntx context.Context, key, value interface{}) bool {
 	svc := value.(*VoltService)
-	if err:= svc.AddDsHsiaFlows(cntx); err != nil {
+	if err := svc.AddDsHsiaFlows(cntx); err != nil {
 		logger.Warnw(ctx, "Add DS hsia flow failed", log.Fields{"service": svc.Name, "Error": err})
 	}
 	return true
@@ -1185,7 +1205,7 @@
 // DelDsHsiaFlows to delete hsia flows
 func DelDsHsiaFlows(cntx context.Context, key, value interface{}) bool {
 	svc := value.(*VoltService)
-	if err:= svc.DelDsHsiaFlows(cntx); err != nil {
+	if err := svc.DelDsHsiaFlows(cntx); err != nil {
 		logger.Warnw(ctx, "Delete DS hsia flow failed", log.Fields{"service": svc.Name, "Error": err})
 	}
 	return true
@@ -1194,7 +1214,7 @@
 // DelUsHsiaFlows to delete upstream hsia flows
 func DelUsHsiaFlows(cntx context.Context, key, value interface{}) bool {
 	svc := value.(*VoltService)
-	if err:= svc.DelUsHsiaFlows(cntx); err != nil {
+	if err := svc.DelUsHsiaFlows(cntx); err != nil {
 		logger.Warnw(ctx, "Delete US hsia flow failed", log.Fields{"service": svc.Name, "Error": err})
 	}
 	return true
@@ -1226,11 +1246,11 @@
 	if !vpv.FlowsApplied || vgcRebooted {
 		if vpv.DhcpRelay {
 			if err := vpv.AddUsDhcpFlows(cntx); err != nil {
-				statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+				statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 				vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 			}
 			if err := vpv.AddDsDhcpFlows(cntx); err != nil {
-				statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+				statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 				vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 			}
 			logger.Infow(ctx, "ICMPv6 MC Group modification will not be triggered to rwcore for ",
@@ -1238,18 +1258,18 @@
 			//vpv.updateICMPv6McGroup(true)
 		} else if vpv.ArpRelay {
 			if err := vpv.AddUsArpFlows(cntx); err != nil {
-				statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+				statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 				vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 			}
 			logger.Info(ctx, "ARP trap rules not added in downstream direction")
 
 		} else if vpv.PppoeIa {
 			if err := vpv.AddUsPppoeFlows(cntx); err != nil {
-				statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+				statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 				vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 			}
 			if err := vpv.AddDsPppoeFlows(cntx); err != nil {
-				statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+				statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 				vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 			}
 		}
@@ -1264,36 +1284,36 @@
 	// Delete HSIA & DHCP flows before deleting IGMP flows
 	if vpv.FlowsApplied || vgcRebooted {
 		if vpv.DhcpRelay {
-			if err:= vpv.DelUsDhcpFlows(cntx); err != nil {
+			if err := vpv.DelUsDhcpFlows(cntx); err != nil {
 				logger.Warnw(ctx, "Delete US hsia flow failed", log.Fields{"port": vpv.Port, "SVlan": vpv.SVlan, "CVlan": vpv.CVlan,
 					"UniVlan": vpv.UniVlan, "Error": err})
 			}
 			logger.Infow(ctx, "ICMPv6 MC Group modification will not be triggered to rwcore  for ",
 				log.Fields{"port": vpv.Port})
 			if err := vpv.DelDsDhcpFlows(cntx); err != nil {
-				statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+				statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 				vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 			}
 			//vpv.updateICMPv6McGroup(false)
 		} else if vpv.ArpRelay {
 			if err := vpv.DelUsArpFlows(cntx); err != nil {
-				statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+				statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 				vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 			}
 		} else if vpv.PppoeIa {
 			if err := vpv.DelUsPppoeFlows(cntx); err != nil {
-				statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+				statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 				vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 			}
 			if err := vpv.DelDsPppoeFlows(cntx); err != nil {
-				statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+				statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 				vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 			}
 		}
 		vpv.FlowsApplied = false
 		vpv.WriteToDb(cntx)
 	}
-	if err:= vpv.DelIgmpFlows(cntx); err != nil {
+	if err := vpv.DelIgmpFlows(cntx); err != nil {
 		logger.Warnw(ctx, "Delete igmp flow failed", log.Fields{"port": vpv.Port, "SVlan": vpv.SVlan, "CVlan": vpv.CVlan,
 			"UniVlan": vpv.UniVlan, "Error": err})
 	}
@@ -1334,33 +1354,16 @@
 		logger.Debugw(ctx, "Adding US DHCP flows", log.Fields{"Device": device})
 		if err1 := vpv.PushFlows(cntx, vd, flows); err1 != nil {
 			//push ind here ABHI
-			statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err1)
+			statusCode, statusMessage := errorCodes.GetErrorInfo(err1)
 			vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 		}
 	} else {
 		logger.Errorw(ctx, "US DHCP Flow Add Failed", log.Fields{"Reason": err.Error(), "Device": device})
 		//push ind here ABHI
-		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+		statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 
 	}
-	/*
-	flows, err = vpv.BuildUsDhcp6Flows()
-	if err == nil {
-		logger.Debugw(ctx, "Adding US DHCP6 flows", log.Fields{"Device": device})
-		if err1 := vpv.PushFlows(vd, flows); err1 != nil {
-			//pussh ind here ABHI
-			statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err1)
-			vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
-
-		}
-	} else {
-		logger.Errorw(ctx, "US DHCP6 Flow Add Failed", log.Fields{"Reason": err.Error(), "Device": device})
-		//push ind here ABHI
-		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
-		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
-
-	}*/
 	return nil
 }
 
@@ -1388,33 +1391,17 @@
 	if err == nil {
 		if err1 := vpv.PushFlows(cntx, vd, flows); err1 != nil {
 			//push ind here and procced
-			statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err1)
+			statusCode, statusMessage := errorCodes.GetErrorInfo(err1)
 			vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 
 		}
 	} else {
 		logger.Errorw(ctx, "DS DHCP Flow Add Failed", log.Fields{"Reason": err.Error()})
 		//send ind here and proceed
-		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+		statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 
 	}
-	/*
-	flows, err = vpv.BuildDsDhcp6Flows()
-	if err == nil {
-		if err1 := vpv.PushFlows(vd, flows); err1 != nil {
-			//push ind and proceed
-			statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err1)
-			vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
-
-		}
-	} else {
-		logger.Errorw(ctx, "DS DHCP6 Flow Add Failed", log.Fields{"Reason": err.Error()})
-		//Send ind here and proceed
-		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
-		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
-
-	}*/
 	if GetApplication().GetVendorID() != Radisys {
 		vd.GlobalDhcpFlowAdded = true
 	}
@@ -1424,12 +1411,12 @@
 // DelDhcpFlows deletes both US & DS DHCP flows applied for this Vnet instantiated on the port
 func (vpv *VoltPortVnet) DelDhcpFlows(cntx context.Context) {
 	if err := vpv.DelUsDhcpFlows(cntx); err != nil {
-		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+		statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 	}
 
 	if err := vpv.DelDsDhcpFlows(cntx); err != nil {
-		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+		statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 	}
 }
@@ -1445,15 +1432,10 @@
 
 	err = vpv.delDhcp4Flows(cntx, device)
 	if err != nil {
-		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+		statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 	}
-	/*
-	err = vpv.delDhcp6Flows(device)
-	if err != nil {
-		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
-		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
-	}*/
+
 	return nil
 }
 
@@ -1465,16 +1447,6 @@
 	logger.Errorw(ctx, "US DHCP Flow Delete Failed", log.Fields{"Reason": err.Error()})
 	return err
 }
-/*
-func (vpv *VoltPortVnet) delDhcp6Flows(device *VoltDevice) error {
-	flows, err := vpv.BuildUsDhcp6Flows()
-	if err == nil {
-		return vpv.RemoveFlows(device, flows)
-	}
-	logger.Errorw(ctx, "US DHCP6 Flow Delete Failed", log.Fields{"Reason": err.Error()})
-	return err
-
-}*/
 
 // DelDsDhcpFlows delete the DHCP flows applied for this Vnet instantiated on the port
 // Write the status of the VPV to the DB once the delete is scheduled
@@ -1486,15 +1458,15 @@
 	}
 	err = vpv.delDsDhcp4Flows(cntx, device)
 	if err != nil {
-		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
+		statusCode, statusMessage := errorCodes.GetErrorInfo(err)
 		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
 	}
 	/*
-	err = vpv.delDsDhcp6Flows(device)
-	if err != nil {
-		statusCode, statusMessage := infraerrorCodes.GetErrorInfo(err)
-		vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
-	}*/
+		err = vpv.delDsDhcp6Flows(device)
+		if err != nil {
+			statusCode, statusMessage := errorCodes.GetErrorInfo(err)
+			vpv.FlowInstallFailure("VGC processing failure", statusCode, statusMessage)
+		}*/
 	return nil
 }
 
@@ -2126,14 +2098,8 @@
 	subFlow := of.NewVoltSubFlow()
 	subFlow.SetTableID(0)
 
-        if GetApplication().GetVendorID() == Radisys {
-                if err := vpv.setUsMatchVlan(subFlow); err != nil {
-                        return nil, err
-                }
-        } else {
-                subFlow.SetMatchVlan(vpv.UniVlan)
-                subFlow.SetSetVlan(vpv.CVlan)
-        }
+	subFlow.SetMatchVlan(vpv.UniVlan)
+	subFlow.SetSetVlan(vpv.CVlan)
 
 	uniport, err := GetApplication().GetPortID(vpv.Port)
 	if err != nil {
@@ -3226,7 +3192,7 @@
 func (vv *VoltVnet) JsonMarshal() ([]byte, error) {
 	return json.Marshal(VoltVnet{
 		VnetConfig: vv.VnetConfig,
-		Version: vv.Version,
+		Version:    vv.Version,
 		VnetOper: VnetOper{
 			PendingDeleteFlow:     vv.VnetOper.PendingDeleteFlow,
 			DeleteInProgress:      vv.VnetOper.DeleteInProgress,
diff --git a/internal/pkg/controller/controller.go b/internal/pkg/controller/controller.go
index 3ed1c04..1e76e9e 100644
--- a/internal/pkg/controller/controller.go
+++ b/internal/pkg/controller/controller.go
@@ -544,7 +544,7 @@
 	d, err := v.GetDevice(deviceID)
 	if err != nil {
 		logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": deviceID, "Error": err})
-		return nil, err
+		return nil, nil
 	}
 	return d.GetAllFlows(), nil
 }
diff --git a/voltha-go-controller/nbi/sadisbwprofile.go b/voltha-go-controller/nbi/bwprofile.go
similarity index 100%
rename from voltha-go-controller/nbi/sadisbwprofile.go
rename to voltha-go-controller/nbi/bwprofile.go
diff --git a/voltha-go-controller/nbi/igmpproxy.go b/voltha-go-controller/nbi/igmpproxy.go
new file mode 100644
index 0000000..43005b0
--- /dev/null
+++ b/voltha-go-controller/nbi/igmpproxy.go
@@ -0,0 +1,116 @@
+/*
+* 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 nbi
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"net/http"
+	"strconv"
+	"strings"
+
+	app "voltha-go-controller/internal/pkg/application"
+	"voltha-go-controller/internal/pkg/of"
+	"voltha-go-controller/log"
+)
+
+// IgmpProxy - configurations
+type IgmpProxy struct {
+	FastLeave               string `json:"fastleave"`
+	LastQueryInterval       int    `json:"lastqueryinterval"`
+	MaxResp                 int    `json:"maxresp"`
+	EnableIgmpProvisioning  string `json:"enableigmpprovisioning"`
+	GlobalConnectPointMode  string `json:"globalconnectpointmode"`
+	GlobalConnectPoint      string `json:"globalconnectpoint"`
+	SourceDeviceAndPort     string `json:"sourcedeviceandport"`
+	OutgoingIgmpVlanID      int    `json:"outgoingigmpvlanid"`
+	OutgoingIgmpInnerVlanID int    `json:"outgoingigmpinnervlanid"`
+	OutgoingIgmpWithV3      string `json:"outgoingigmpwithv3"`
+	IgmpCos                 int    `json:"igmpcos"`
+	IgmpUniCos              int    `json:"igmpunicos"`
+	PeriodicQuery           string `json:"periodicquery"`
+	KeepAliveInterval       int    `json:"keepaliveinterval"`
+	KeepAliveCount          int    `json:"keepalivecount"`
+	RequestDsIgmpPackets    bool   `json:"requestdsigmppackets"`
+}
+
+// IgmpProxyHandle struct
+type IgmpProxyHandle struct {
+}
+
+// ServeHTTP to serve http request
+func (iph *IgmpProxyHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL})
+	switch r.Method {
+	case "POST":
+		iph.AddIgmpProxyInfo(context.Background(), w, r)
+	case "DELETE":
+		iph.DelIgmpProxyInfo(context.Background(), w, r)
+	default:
+		logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method})
+	}
+}
+
+// AddIgmpProxyInfo to add igmp proxy info
+func (iph *IgmpProxyHandle) AddIgmpProxyInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
+
+	// Get the payload to process the request
+	d := new(bytes.Buffer)
+	if _, err := d.ReadFrom(r.Body); err != nil {
+		logger.Warnw(ctx, "Error reading buffer", log.Fields{"Reason": err.Error()})
+		return
+	}
+
+	// Unmarshal the request into service configuration structure
+	req := &IgmpProxy{}
+	if err := json.Unmarshal(d.Bytes(), req); err != nil {
+		logger.Warnw(ctx, "Unmarshal Failed", log.Fields{"Reason": err.Error()})
+		http.Error(w, err.Error(), http.StatusConflict)
+		return
+	}
+	logger.Debugw(ctx, "Received-northbound-add-service-request", log.Fields{"req": req})
+
+	go iph.addIgmpProxy(cntx, w, req)
+}
+
+// DelIgmpProxyInfo to delete igmp proxy info
+func (iph *IgmpProxyHandle) DelIgmpProxyInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
+}
+
+func (iph *IgmpProxyHandle) addIgmpProxy(cntx context.Context, w http.ResponseWriter, req *IgmpProxy) {
+	var config McastConfig
+
+	if mvp := app.GetApplication().GetMvlanProfileByTag(of.VlanType(req.OutgoingIgmpVlanID)); mvp == nil {
+		logger.Errorw(ctx, "MVLAN ID not configured", log.Fields{"mvlan": req.OutgoingIgmpVlanID})
+		http.Error(w, "MVLAN profile does not exists", http.StatusConflict)
+		return
+	}
+	config.OltSerialNum = req.SourceDeviceAndPort
+	var splits = strings.Split(req.SourceDeviceAndPort, "/")
+	config.OltSerialNum = splits[0]
+	config.MvlanProfileID = "mvlan" + strconv.Itoa(req.OutgoingIgmpVlanID)
+
+	logger.Errorw(ctx, "IgmpProxy", log.Fields{"config": config})
+
+	if err := app.GetApplication().AddMcastConfig(cntx, config.MvlanProfileID, config.IgmpProfileID,
+		config.IgmpProxyIP, config.OltSerialNum); err != nil {
+		logger.Errorw(ctx, "northbound-add-mcast-config-failed", log.Fields{"config": config, "Error": err})
+		http.Error(w, err.Error(), http.StatusConflict)
+		return
+	}
+
+}
diff --git a/voltha-go-controller/nbi/mvlan.go b/voltha-go-controller/nbi/mvlan.go
new file mode 100644
index 0000000..a4109d5
--- /dev/null
+++ b/voltha-go-controller/nbi/mvlan.go
@@ -0,0 +1,153 @@
+/*
+* 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 nbi
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"net/http"
+	"strconv"
+
+	app "voltha-go-controller/internal/pkg/application"
+	"voltha-go-controller/internal/pkg/of"
+	common "voltha-go-controller/internal/pkg/types"
+	"voltha-go-controller/log"
+
+	"github.com/gorilla/mux"
+)
+
+// McastConfig structure
+type McastConfig struct {
+	MvlanProfileID string `json:"mvlanProfile"`
+	IgmpProfileID  string `json:"igmpProfile"`
+	IgmpProxyIP    string `json:"igmpProxyIp"`
+	OltSerialNum   string `json:"oltSerialNum"`
+}
+
+// MvlanProfileCfg structure
+type MvlanProfileCfg struct {
+	*MvlanProfile `json:"mvlanProfile"`
+}
+
+// Mvlan - configurations
+type Mvlan struct {
+	IngressVlan     int `json:"ingressvlan"`
+	EgressVlan      int `json:"egressvlan"`
+	EgressInnerVlan int `json:"egressinnervlan"`
+}
+
+// MvlanProfile structure
+type MvlanProfile struct {
+	Name                 string                                `json:"name"`
+	Mvlan                of.VlanType                           `json:"mvlan"`
+	PonVlan              of.VlanType                           `json:"ponVlan"`
+	Groups               map[string][]string                   `json:"groups"`
+	Proxy                map[string]common.MulticastGroupProxy `json:"proxy"`
+	IsChannelBasedGroup  bool                                  `json:"isChannelBasedGroup"`
+	OLTSerialNum         []string                              `json:"oltserialnum"`
+	ActiveChannelsPerSub int                                   `json:"ActiveChannelsPerSub"`
+}
+
+// IGMPCfg structure
+type IGMPCfg struct {
+	AppID struct {
+		IgmpApp struct {
+			Parameters common.IGMPConfig `json:"igmpproxy"`
+		} `json:"org.opencord.igmpproxy"`
+	} `json:"apps"`
+}
+
+// MulticastHandle struct
+type MulticastHandle struct {
+}
+
+// ServeHTTP to serve http request
+func (iph *MulticastHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL})
+	switch r.Method {
+	case "POST":
+		iph.AddMvlanInfo(context.Background(), w, r)
+	case "DELETE":
+		iph.DelMvlanInfo(context.Background(), w, r)
+	default:
+		logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method})
+	}
+}
+
+// AddMvlanInfo to add igmp proxy info
+func (iph *MulticastHandle) AddMvlanInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
+
+	// Get the payload to process the request
+	d := new(bytes.Buffer)
+	if _, err := d.ReadFrom(r.Body); err != nil {
+		logger.Warnw(ctx, "Error reading buffer", log.Fields{"Reason": err.Error()})
+		return
+	}
+
+	// Unmarshal the request into service configuration structure
+	req := &Mvlan{}
+	if err := json.Unmarshal(d.Bytes(), req); err != nil {
+		logger.Warnw(ctx, "Unmarshal Failed", log.Fields{"Reason": err.Error()})
+		http.Error(w, err.Error(), http.StatusConflict)
+		return
+	}
+	logger.Debugw(ctx, "Received-northbound-add-service-request", log.Fields{"req": req})
+
+	go iph.addMvlan(cntx, w, req)
+}
+
+// DelMvlanInfo to delete igmp proxy info
+func (iph *MulticastHandle) DelMvlanInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
+	logger.Info(ctx, "Inside DelMvlanInfo method")
+
+	vars := mux.Vars(r)
+	egressvlan := vars["egressvlan"]
+
+	logger.Infow(ctx, "Inside DelMvlanInfo method", log.Fields{"req": egressvlan})
+
+	name := "mvlan" + egressvlan
+	// HTTP response with 202 accepted for service delete request
+	w.WriteHeader(http.StatusAccepted)
+
+	logger.Infow(ctx, "Inside DelMvlanInfo method", log.Fields{"name": name})
+	err := app.GetApplication().DelMvlanProfile(cntx, name)
+	if err != nil {
+		logger.Errorw(cntx, "Failed to delete Mvlan profile", log.Fields{"Error": err})
+		return
+	}
+}
+
+func (iph *MulticastHandle) addMvlan(cntx context.Context, w http.ResponseWriter, req *Mvlan) {
+	var config MvlanProfile
+	var groups []string
+
+	groups = append(groups, "225.0.0.0-239.255.255.255")
+	config.Name = "mvlan" + strconv.Itoa(req.EgressVlan)
+	config.Mvlan = of.VlanType(req.EgressVlan)
+	config.PonVlan = of.VlanType(req.EgressInnerVlan)
+	config.Groups = make(map[string][]string)
+	config.Groups["default"] = groups
+
+	if err := app.GetApplication().AddMvlanProfile(cntx, config.Name, config.Mvlan, config.PonVlan, config.Groups,
+		config.IsChannelBasedGroup, config.OLTSerialNum,
+		255, config.Proxy); err != nil {
+		logger.Errorw(ctx, "northbound-add-mvlan-failed", log.Fields{"mvlan": config.Name, "Reason": err.Error()})
+		http.Error(w, err.Error(), http.StatusConflict)
+		return
+	}
+	logger.Debugw(ctx, "northbound-add-mvlan-successful", log.Fields{"mvlan": config.Name})
+}
diff --git a/voltha-go-controller/nbi/netConfig.go b/voltha-go-controller/nbi/netConfig.go
new file mode 100644
index 0000000..0e8e664
--- /dev/null
+++ b/voltha-go-controller/nbi/netConfig.go
@@ -0,0 +1,124 @@
+/*
+* 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 nbi
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"net/http"
+	app "voltha-go-controller/internal/pkg/application"
+	"voltha-go-controller/log"
+)
+
+type NetConfig struct {
+	App Apps `json:"apps"`
+}
+
+type Apps struct {
+	SubscriberBW SubscriberBW `json:"org.opencord.sadis"`
+	IgmpProxy    *IgmpProxy   `json:"org.opencord.igmpproxy"`
+	McastInfo    *McastInfo   `json:"org.onosproject.core"`
+}
+type SubscriberBW struct {
+	Bandwidthprofile BWEnteries `json:"bandwidthprofile"`
+	Subscriber       Subscriber `json:"sadis"`
+}
+
+type BWEnteries struct {
+	BWInfo []BWProfile `json:"entries"`
+}
+type Subscriber struct {
+	SubscriberInfo []SubscriberDeviceInfo `json:"entries"`
+}
+
+type McastInfo struct {
+	Multicast *Mvlan `json:"multicast"`
+}
+
+type NetConfigHandle struct {
+}
+
+func init() {
+	// Setup this package so that it's log level can be modified at run time
+	var err error
+	logger, err = log.AddPackageWithDefaultParam()
+	if err != nil {
+		panic(err)
+	}
+}
+
+// ServeHTTP to serve http request
+func (nch *NetConfigHandle) NetConfigServeHTTP(w http.ResponseWriter, r *http.Request) {
+	logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL})
+	switch r.Method {
+	case "POST":
+		nch.AddNetConfigInfo(ctx, w, r)
+	default:
+		logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method})
+	}
+}
+
+// Populate the network configuration information
+func (nch *NetConfigHandle) AddNetConfigInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
+
+	// Get the payload to process the request
+	d := new(bytes.Buffer)
+	if _, err := d.ReadFrom(r.Body); err != nil {
+		logger.Warnw(ctx, "Error reading buffer", log.Fields{"Reason": err.Error()})
+		return
+	}
+
+	// Unmarshal the request into Network configuration structure
+	req := &NetConfig{}
+	if err := json.Unmarshal(d.Bytes(), req); err != nil {
+		logger.Warnw(ctx, "Unmarshal Failed", log.Fields{"Reason": err.Error()})
+		http.Error(w, err.Error(), http.StatusConflict)
+		return
+	}
+	logger.Debugw(ctx, "Received-northbound-network-configuration-request", log.Fields{"req": req, "d": d.String()})
+
+	//va := app.VoltApplication{}
+
+	for _, bwprofile := range req.App.SubscriberBW.Bandwidthprofile.BWInfo {
+		metercfg := app.VoltMeter{
+			Name: bwprofile.ID,
+			Cir:  bwprofile.CommittedInformationRate,
+			Cbs:  bwprofile.CommittedBurstSize,
+			Pir:  bwprofile.PeakInformationRate,
+			Pbs:  bwprofile.PeakBurstSize,
+			Air:  bwprofile.AssuredInformationRate,
+			Gir:  bwprofile.GuaranteedInformationRate,
+			Eir:  bwprofile.ExceededInformationRate,
+			Ebs:  bwprofile.ExceededBurstSize,
+		}
+		app.GetApplication().AddMeterProf(cntx, metercfg)
+	}
+
+	for _, subscriberInfo := range req.App.SubscriberBW.Subscriber.SubscriberInfo {
+		addAllService(cntx, &subscriberInfo)
+	}
+
+	if req.App.McastInfo != nil {
+		mch := MulticastHandle{}
+		mch.addMvlan(cntx, w, req.App.McastInfo.Multicast)
+	}
+
+	if req.App.IgmpProxy != nil {
+		iph := IgmpProxyHandle{}
+		iph.addIgmpProxy(cntx, w, req.App.IgmpProxy)
+	}
+}
diff --git a/voltha-go-controller/nbi/rest.go b/voltha-go-controller/nbi/rest.go
index 7edafdc..e8a7e50 100644
--- a/voltha-go-controller/nbi/rest.go
+++ b/voltha-go-controller/nbi/rest.go
@@ -33,7 +33,9 @@
 	SubscribersPath                   string = "/subscribers/{id}"
 	ProfilesPath                      string = "/profiles/{id}"
 	IgmpProxyPath                     string = "/igmp-proxy"
-	MulticastPath                     string = "/multicast"
+	IgmpProxyDeletePath               string = "/igmp-proxy/{outgoingigmpvlanid}"
+	MulticastPath                     string = "/multicast/"
+	MulticastDeletePath               string = "/multicast/{egressvlan}"
 	FlowsPath                         string = "/flows"
 	DevicesPath                       string = "/devices"
 	PortsPath                         string = "/devices/ports"
@@ -56,6 +58,7 @@
 	GroupsPath                        string = "/groups"
 	GroupsByIdPath                    string = "/groups/{id}"
 	OltFlowServicePath                string = "/oltflowservice"
+	NetConfigPath                     string = "/network/configurations"
 )
 
 // RestStart to execute for API
@@ -65,7 +68,9 @@
 	mu.HandleFunc(SubscribersPath, (&SubscriberHandle{}).ServeHTTP)
 	mu.HandleFunc(ProfilesPath, (&ProfileHandle{}).ServeHTTP)
 	mu.HandleFunc(IgmpProxyPath, (&IgmpProxyHandle{}).ServeHTTP)
+	mu.HandleFunc(IgmpProxyDeletePath, (&IgmpProxyHandle{}).ServeHTTP)
 	mu.HandleFunc(MulticastPath, (&MulticastHandle{}).ServeHTTP)
+	mu.HandleFunc(MulticastDeletePath, (&MulticastHandle{}).ServeHTTP)
 	mu.HandleFunc(FlowsPath, (&onos_nbi.FlowHandle{}).ServeHTTP)
 	mu.HandleFunc(FlowsPerDeviceIDPath, (&onos_nbi.FlowHandle{}).ServeHTTP)
 	mu.HandleFunc(FlowPerDeviceIDFlowIDPath, (&onos_nbi.FlowHandle{}).ServeHTTP)
@@ -88,7 +93,7 @@
 	mu.HandleFunc(GroupsPath, (&onos_nbi.GroupsHandle{}).GroupServeHTTP)
 	mu.HandleFunc(GroupsByIdPath, (&onos_nbi.GroupsHandle{}).GroupServeHTTP)
 	mu.HandleFunc(OltFlowServicePath, (&onos_nbi.OltFlowServiceHandle{}).ServeHTTP)
-
+	mu.HandleFunc(NetConfigPath, (&NetConfigHandle{}).NetConfigServeHTTP)
 	err := http.ListenAndServe(":8181", mu)
 	logger.Infow(ctx, "Rest Server Started", log.Fields{"Error": err})
 }
diff --git a/voltha-go-controller/nbi/sadisigmpproxy.go b/voltha-go-controller/nbi/sadisigmpproxy.go
deleted file mode 100644
index 5d07229..0000000
--- a/voltha-go-controller/nbi/sadisigmpproxy.go
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-* 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 nbi
-
-import (
-        "bytes"
-	"context"
-        "encoding/json"
-        "net/http"
-	"strings"
-	"strconv"
-
-	app "voltha-go-controller/internal/pkg/application"
-	"voltha-go-controller/internal/pkg/of"
-        "voltha-go-controller/log"
-)
-
-// IgmpProxy - configurations
-type IgmpProxy struct {
-        FastLeave               string `json:"fastleave"`
-        LastQueryInterval       int    `json:"lastqueryinterval"`
-        MaxResp                 int    `json:"maxresp"`
-        EnableIgmpProvisioning  string `json:"enableigmpprovisioning"`
-        GlobalConnectPointMode  string `json:"globalconnectpointmode"`
-        GlobalConnectPoint      string `json:"globalconnectpoint"`
-        SourceDeviceAndPort     string `json:"sourcedeviceandport"`
-        OutgoingIgmpVlanID      int    `json:"outgoingigmpvlanid"`
-        OutgoingIgmpInnerVlanID int    `json:"outgoingigmpinnervlanid"`
-        OutgoingIgmpWithV3      string `json:"outgoingigmpwithv3"`
-        IgmpCos                 int    `json:"igmpcos"`
-        IgmpUniCos              int    `json:"igmpunicos"`
-        PeriodicQuery           string `json:"periodicquery"`
-        KeepAliveInterval       int    `json:"keepaliveinterval"`
-        KeepAliveCount          int    `json:"keepalivecount"`
-        RequestDsIgmpPackets    bool   `json:"requestdsigmppackets"`
-}
-
-// IgmpProxyHandle struct
-type IgmpProxyHandle struct {
-}
-
-// ServeHTTP to serve http request
-func (iph *IgmpProxyHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-        logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL})
-        switch r.Method {
-        case "POST":
-                iph.AddIgmpProxyInfo(context.Background(), w, r)
-        case "DELETE":
-                iph.DelIgmpProxyInfo(context.Background(), w, r)
-        default:
-                logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method})
-        }
-}
-
-// AddIgmpProxyInfo to add igmp proxy info
-func (iph *IgmpProxyHandle) AddIgmpProxyInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
-
-        // Get the payload to process the request
-        d := new(bytes.Buffer)
-        if _, err := d.ReadFrom(r.Body);  err != nil {
-                logger.Warnw(ctx, "Error reading buffer", log.Fields{"Reason": err.Error()})
-                return
-        }
-
-        // Unmarshal the request into service configuration structure
-        req := &IgmpProxy{}
-        if err := json.Unmarshal(d.Bytes(), req); err != nil {
-                logger.Warnw(ctx, "Unmarshal Failed", log.Fields{"Reason": err.Error()})
-                http.Error(w, err.Error(), http.StatusConflict)
-                return
-        }
-        if mvp := app.GetApplication().GetMvlanProfileByTag(of.VlanType(req.OutgoingIgmpVlanID)); mvp == nil {
-                logger.Errorw(ctx, "MVLAN ID not configured", log.Fields{"mvlan": req.OutgoingIgmpVlanID})
-                http.Error(w, "MVLAN profile does not exists", http.StatusConflict)
-                return
-        }
-        logger.Debugw(ctx, "Received-northbound-add-service-request", log.Fields{"req": req})
-
-        go iph.addIgmpProxy(cntx, w, req)
-}
-
-// DelIgmpProxyInfo to delete igmp proxy info
-func (iph *IgmpProxyHandle) DelIgmpProxyInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
-
-}
-
-func (iph *IgmpProxyHandle) addIgmpProxy(cntx context.Context, w http.ResponseWriter, req *IgmpProxy) {
-	var config McastConfig
-
-	config.OltSerialNum = req.SourceDeviceAndPort
-	//config.MvlanProfileID = mvp.Name
-	//config.IgmpProfileID = 
-	//config.IgmpProxyIP = 
-	var splits = strings.Split(req.SourceDeviceAndPort, "/")
-	config.OltSerialNum = splits[0]
-	config.MvlanProfileID = "mvlan" + strconv.Itoa(req.OutgoingIgmpVlanID)
-
-	logger.Errorw(ctx, "IgmpProxy", log.Fields{"config":config})
-
-        if err := app.GetApplication().AddMcastConfig(cntx, config.MvlanProfileID, config.IgmpProfileID,
-                config.IgmpProxyIP, config.OltSerialNum); err != nil {
-                logger.Errorw(ctx, "northbound-add-mcast-config-failed", log.Fields{"config": config, "Error": err})
-                http.Error(w, err.Error(), http.StatusConflict)
-                return
-        }
-
-}
-
diff --git a/voltha-go-controller/nbi/sadismvlan.go b/voltha-go-controller/nbi/sadismvlan.go
deleted file mode 100644
index 2242188..0000000
--- a/voltha-go-controller/nbi/sadismvlan.go
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-* 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 nbi
-
-import (
-        "bytes"
-	"context"
-        "encoding/json"
-        "net/http"
-        "strconv"
-
-        app "voltha-go-controller/internal/pkg/application"
-	"voltha-go-controller/internal/pkg/types"
-        "voltha-go-controller/internal/pkg/of"
-        "voltha-go-controller/log"
-)
-// McastConfig structure
-type McastConfig struct {
-        MvlanProfileID string `json:"mvlanProfile"`
-        IgmpProfileID  string `json:"igmpProfile"`
-        IgmpProxyIP    string `json:"igmpProxyIp"`
-        OltSerialNum   string `json:"oltSerialNum"`
-}
-
-// MvlanProfileCfg structure
-type MvlanProfileCfg struct {
-        *MvlanProfile `json:"mvlanProfile"`
-}
-
-// Mvlan - configurations
-type Mvlan struct {
-        IngressVlan     int `json:"ingressvlan"`
-        EgressVlan      int `json:"egressvlan"`
-        EgressInnerVlan int `json:"egressinnervlan"`
-}
-
-// MvlanProfile structure
-type MvlanProfile struct {
-        Name                 string                                `json:"name"`
-        Mvlan                of.VlanType                           `json:"mvlan"`
-        PonVlan              of.VlanType                           `json:"ponVlan"`
-        Groups               map[string][]string                   `json:"groups"`
-        Proxy                map[string]common.MulticastGroupProxy `json:"proxy"`
-        IsChannelBasedGroup  bool                                  `json:"isChannelBasedGroup"`
-        OLTSerialNum         []string                              `json:"oltserialnum"`
-        ActiveChannelsPerSub int                                   `json:"ActiveChannelsPerSub"`
-}
-
-// IGMPCfg structure
-type IGMPCfg struct {
-        AppID struct {
-                IgmpApp struct {
-                        Parameters common.IGMPConfig `json:"igmpproxy"`
-                } `json:"org.opencord.igmpproxy"`
-        } `json:"apps"`
-}
-
-// MulticastHandle struct
-type MulticastHandle struct {
-}
-
-// ServeHTTP to serve http request
-func (iph *MulticastHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-        logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL})
-        switch r.Method {
-        case "POST":
-                iph.AddMvlanInfo(context.Background(), w, r)
-        case "DELETE":
-                iph.DelMvlanInfo(context.Background(), w, r)
-        default:
-                logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method})
-        }
-}
-
-// AddMvlanInfo to add igmp proxy info
-func (iph *MulticastHandle) AddMvlanInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
-
-        // Get the payload to process the request
-        d := new(bytes.Buffer)
-	if _, err := d.ReadFrom(r.Body);  err != nil {
-		logger.Warnw(ctx, "Error reading buffer", log.Fields{"Reason": err.Error()})
-		return
-	}
-
-
-        // Unmarshal the request into service configuration structure
-        req := &Mvlan{}
-        if err := json.Unmarshal(d.Bytes(), req); err != nil {
-                logger.Warnw(ctx, "Unmarshal Failed", log.Fields{"Reason": err.Error()})
-                http.Error(w, err.Error(), http.StatusConflict)
-                return
-        }
-        logger.Debugw(ctx, "Received-northbound-add-service-request", log.Fields{"req": req})
-
-        go iph.addMvlan(cntx, w, req)
-}
-
-// DelMvlanInfo to delete igmp proxy info
-func (iph *MulticastHandle) DelMvlanInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
-
-}
-
-func (iph *MulticastHandle) addMvlan(cntx context.Context, w http.ResponseWriter, req *Mvlan) {
-	var config MvlanProfile
-	var groups []string
-
-	groups = append(groups, "225.0.0.0-239.255.255.255")
-	config.Name = "mvlan" + strconv.Itoa(req.EgressVlan)
-	config.Mvlan = of.VlanType(req.EgressVlan)
-	config.PonVlan = of.VlanType(req.EgressInnerVlan)
-	config.Groups = make(map[string][]string)
-	config.Groups["default"] = groups
-
-	if err := app.GetApplication().AddMvlanProfile(cntx, config.Name, config.Mvlan, config.PonVlan, config.Groups,
-							config.IsChannelBasedGroup, config.OLTSerialNum,
-							255, config.Proxy); err != nil {
-                logger.Errorw(ctx, "northbound-add-mvlan-failed", log.Fields{"mvlan": config.Name, "Reason": err.Error()})
-                http.Error(w, err.Error(), http.StatusConflict)
-                return
-        }
-        logger.Debugw(ctx, "northbound-add-mvlan-successful", log.Fields{"mvlan": config.Name})
-}
diff --git a/voltha-go-controller/nbi/subscriber.go b/voltha-go-controller/nbi/subscriber.go
index dca6fa2..b8feb67 100644
--- a/voltha-go-controller/nbi/subscriber.go
+++ b/voltha-go-controller/nbi/subscriber.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 nbi
 
@@ -23,12 +23,13 @@
 	"net/http"
 	"strconv"
 
-	"github.com/google/gopacket/layers"
-	"github.com/gorilla/mux"
 	"voltha-go-controller/internal/pkg/application"
 	app "voltha-go-controller/internal/pkg/application"
 	"voltha-go-controller/internal/pkg/of"
 	"voltha-go-controller/log"
+
+	"github.com/google/gopacket/layers"
+	"github.com/gorilla/mux"
 )
 
 //SubscriberDeviceInfo - Subcriber Device Info
@@ -68,14 +69,13 @@
 	IsPppoeRequired               bool   `json:"isPppoeRequired"`
 }
 
-
 func init() {
-        // Setup this package so that it's log level can be modified at run time
-        var err error
-        logger, err = log.AddPackageWithDefaultParam()
-        if err != nil {
-                panic(err)
-        }
+	// Setup this package so that it's log level can be modified at run time
+	var err error
+	logger, err = log.AddPackageWithDefaultParam()
+	if err != nil {
+		panic(err)
+	}
 }
 
 // SubscriberHandle handle SubscriberInfo Requests
@@ -100,7 +100,7 @@
 
 	// Get the payload to process the request
 	d := new(bytes.Buffer)
-	if _, err := d.ReadFrom(r.Body);  err != nil {
+	if _, err := d.ReadFrom(r.Body); err != nil {
 		logger.Warnw(ctx, "Error reading buffer", log.Fields{"Reason": err.Error()})
 		return
 	}
@@ -125,7 +125,10 @@
 	va := app.GetApplication()
 	if len(srvInfo.UniTagList) == 0 {
 		logger.Debugw(ctx, "Received OLT configuration", log.Fields{"req": srvInfo})
-		va.UpdateDeviceConfig(cntx, srvInfo.ID, srvInfo.HardwareIdentifier, srvInfo.NasID, srvInfo.UplinkPort, srvInfo.NniDhcpTrapVid, srvInfo.IPAddress)
+		err := va.AddDeviceConfig(cntx, srvInfo.ID, srvInfo.HardwareIdentifier, srvInfo.NasID, srvInfo.IPAddress, srvInfo.UplinkPort, srvInfo.NniDhcpTrapVid)
+		if err != nil {
+			logger.Warnw(ctx, "Device config addition failed :", log.Fields{"Reason": err.Error()})
+		}
 		return
 	}
 	for _, uniTagInfo := range srvInfo.UniTagList {
@@ -153,33 +156,33 @@
 		vs.ServiceType = uniTagInfo.ServiceName
 
 		if uniTagInfo.ServiceName == app.DPU_MGMT_TRAFFIC ||
-		   uniTagInfo.ServiceName == app.DPU_ANCP_TRAFFIC ||
-		   uniTagInfo.ServiceName == app.FTTB_SUBSCRIBER_TRAFFIC {
+			uniTagInfo.ServiceName == app.DPU_ANCP_TRAFFIC ||
+			uniTagInfo.ServiceName == app.FTTB_SUBSCRIBER_TRAFFIC {
 			vs.UniVlan = vs.CVlan
 			vs.Pbits = append(vs.Pbits, of.PbitMatchAll)
 		} else {
-		if uniTagInfo.UsPonSTagPriority == -1 {
-			vs.Pbits = append(vs.Pbits, of.PbitMatchAll)
-		// Process the p-bits received in the request
-		} else {
-			if uniTagInfo.UsPonSTagPriority < 8 {
-				vs.Pbits = append(vs.Pbits, of.PbitType(uniTagInfo.UsPonCTagPriority))
-			}
+			if uniTagInfo.UsPonSTagPriority == -1 {
+				vs.Pbits = append(vs.Pbits, of.PbitMatchAll)
+				// Process the p-bits received in the request
+			} else {
+				if uniTagInfo.UsPonSTagPriority < 8 {
+					vs.Pbits = append(vs.Pbits, of.PbitType(uniTagInfo.UsPonCTagPriority))
+				}
 
-			if uniTagInfo.UsPonSTagPriority < 8 && uniTagInfo.UsPonSTagPriority != uniTagInfo.DsPonSTagPriority {
-				vs.Pbits = append(vs.Pbits, of.PbitType(uniTagInfo.DsPonCTagPriority))
+				if uniTagInfo.UsPonSTagPriority < 8 && uniTagInfo.UsPonSTagPriority != uniTagInfo.DsPonSTagPriority {
+					vs.Pbits = append(vs.Pbits, of.PbitType(uniTagInfo.DsPonCTagPriority))
+				}
 			}
 		}
-		}
 		//vs.McastService = uniTagInfo.IsIgmpRequired
 		if vs.IgmpEnabled {
 			vs.MvlanProfileName = "mvlan" + strconv.Itoa(uniTagInfo.PonSTag)
 		}
 		/*
-		var err error
-		if vs.MacAddr, err = net.ParseMAC(srvInfo.HardwareIdentifier); err != nil {
-			vs.MacAddr, _ = net.ParseMAC("00:00:00:00:00:00")
-		}*/
+			var err error
+			if vs.MacAddr, err = net.ParseMAC(srvInfo.HardwareIdentifier); err != nil {
+				vs.MacAddr, _ = net.ParseMAC("00:00:00:00:00:00")
+			}*/
 
 		vs.MacAddr, _ = net.ParseMAC("00:00:00:00:00:00")
 		if len(vs.Pbits) == 0 {
@@ -213,7 +216,7 @@
 		}
 		if vs.CVlan != of.VlanAny && vs.SVlan != of.VlanAny {
 			if uniTagInfo.ServiceName == app.DPU_MGMT_TRAFFIC ||
-			   uniTagInfo.ServiceName == app.DPU_ANCP_TRAFFIC {
+				uniTagInfo.ServiceName == app.DPU_ANCP_TRAFFIC {
 				vnetcfg.VlanControl = app.ONUCVlan
 			} else if uniTagInfo.ServiceName == app.FTTB_SUBSCRIBER_TRAFFIC {
 				vnetcfg.VlanControl = app.OLTSVlan