net config restinterface along with mvlan delete rest api

Change-Id: I4d8f5829d4e8b08be7981716cb3cde26cc5a507c
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,