/*
* Copyright 2022-present Open Networking Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
 */

package application

import (
	"encoding/hex"
	"errors"
	"net"
	"sync"

	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"

	cntlr "voltha-go-controller/internal/pkg/controller"
	"voltha-go-controller/internal/pkg/of"
	"voltha-go-controller/internal/pkg/util"
	"github.com/opencord/voltha-lib-go/v7/pkg/log"
)

// DhcpRelayState type
type DhcpRelayState uint8

const (
	// DhcpRelayStateNone constant
	DhcpRelayStateNone DhcpRelayState = iota
	// DhcpRelayStateDiscover constant
	DhcpRelayStateDiscover
	// DhcpRelayStateOffer constant
	DhcpRelayStateOffer
	// DhcpRelayStateRequest constant
	DhcpRelayStateRequest
	// DhcpRelayStateAck constant
	DhcpRelayStateAck
	// DhcpRelayStateNAK constant
	DhcpRelayStateNAK
	// DhcpRelayStateRelease constant
	DhcpRelayStateRelease
)

// RemoteIDType represents data type for various RemoteID types
type RemoteIDType string

// List of RemoteID types supported
const (
        MACAddress      RemoteIDType = "MAC_ADDRESS"
        CustomRemotedID RemoteIDType = "Custom"
)

// MaxLenDhcpv6DUID constant
const MaxLenDhcpv6DUID = 130 // 2: DUID-Type, 128: MaxLen of DUID value

// opt82 constant
const opt82 = 82

// Dhcpv6RelayState type
type Dhcpv6RelayState uint8

const (
	// Dhcpv6RelayStateNone constant
	Dhcpv6RelayStateNone Dhcpv6RelayState = iota
	// Dhcpv6RelayStateSolicit constant
	Dhcpv6RelayStateSolicit
	// Dhcpv6RelayStateReply constant
	Dhcpv6RelayStateReply
	// Dhcpv6RelayStateRelease constant
	Dhcpv6RelayStateRelease
)

var (
	// ErrSessionDoNotExist error type
	ErrSessionDoNotExist = errors.New("Session Doesn't Exist")
)

// IDhcpRelaySession to get dhcp session field value
type IDhcpRelaySession interface {
	GetCircuitID() []byte
	GetRemoteID() []byte
	GetNniVlans() (uint16, uint16)
	GetDhcpState() DhcpRelayState
	GetDhcpv6State() Dhcpv6RelayState
	SetDhcpState(DhcpRelayState)
	SetDhcpv6State(Dhcpv6RelayState)
	SetMacAddr(net.HardwareAddr)
	DhcpResultInd(*layers.DHCPv4)
	Dhcpv6ResultInd(ipv6Addr net.IP, leaseTime uint32)
}

// DhcpRelayVnet : The DHCP relay sessions are stored in a map to be retrieved from when
// a response is received from the network. The map uses the VLANs and the
// the MAC address as key to finding the service
// DHCP Relay Virtual Network hosts a set of DHCP relay sessions that belong
// to the network. It supports two VLANs as its identify. If a single VLAN or
// no VLAN is to be used, those two should be passed as 4096 (VlanNone)
type DhcpRelayVnet struct {
	OuterVlan   uint16
	InnerVlan   uint16
	sessions    map[[6]byte]IDhcpRelaySession
	sessionsv6  map[[MaxLenDhcpv6DUID]byte]IDhcpRelaySession
	sessionLock sync.RWMutex
}

// DhcpNetworks hosts different DHCP networks that in turn hold the DHCP
// sessions
type DhcpNetworks struct {
	Networks map[uint32]*DhcpRelayVnet
}

func init() {
	RegisterPacketHandler(DHCPv4, ProcessUDP4Packet)
	RegisterPacketHandler(DHCPv6, ProcessUDP6Packet)
}

// NewDhcpRelayVnet is constructor for a DHCP Relay Virtual network
func NewDhcpRelayVnet(outerVlan uint16, innerVlan uint16) *DhcpRelayVnet {
	var drv DhcpRelayVnet

	drv.OuterVlan = outerVlan
	drv.InnerVlan = innerVlan
	drv.sessions = make(map[[6]byte]IDhcpRelaySession)
	drv.sessionsv6 = make(map[[MaxLenDhcpv6DUID]byte]IDhcpRelaySession)
	return &drv
}

// GetDhcpVnet to add dhcp vnet
func (dn *DhcpNetworks) GetDhcpVnet(outerVlan uint16, innerVlan uint16) *DhcpRelayVnet {
	comboVlan := uint32(outerVlan)<<16 + uint32(innerVlan)
	drv, ok := dn.Networks[comboVlan]
	if ok {
		return drv
	}
	return nil
}

// AddDhcpVnet to add dhcp vnet
func (dn *DhcpNetworks) AddDhcpVnet(outerVlan uint16, innerVlan uint16) *DhcpRelayVnet {
	comboVlan := uint32(outerVlan)<<16 + uint32(innerVlan)
	if drv, ok := dn.Networks[comboVlan]; ok {
		return drv
	}
	drv := NewDhcpRelayVnet(outerVlan, innerVlan)
	dn.Networks[comboVlan] = drv
	return drv
}

// NewDhcpNetworks to get new dhcp network
func NewDhcpNetworks() *DhcpNetworks {
	var dn DhcpNetworks
	dn.Networks = make(map[uint32]*DhcpRelayVnet)
	return &dn
}

// AddDhcpSession to add dhcp session
func (dn *DhcpNetworks) AddDhcpSession(pkt gopacket.Packet, session IDhcpRelaySession) error {
	var key [6]byte
	ethl := pkt.Layer(layers.LayerTypeEthernet)
	eth, _ := ethl.(*layers.Ethernet)
	addr := eth.SrcMAC
	if len(addr) != 6 {
		logger.Errorw(ctx, "Invalid MAC address", log.Fields{"Addr": addr})
		return errors.New("Invalid MAC address")
	}
	copy(key[:], addr[0:6])

	drv := dn.AddDhcpVnet(session.GetNniVlans())

	drv.sessionLock.Lock()
	drv.sessions[key] = session
	drv.sessionLock.Unlock()
	return nil
}

// DelDhcpSession to delete dhcp session
func (dn *DhcpNetworks) DelDhcpSession(pkt gopacket.Packet, session IDhcpRelaySession) {
	var key [6]byte
	ethl := pkt.Layer(layers.LayerTypeEthernet)
	eth, _ := ethl.(*layers.Ethernet)
	addr := eth.SrcMAC
	if len(addr) != 6 {
		logger.Errorw(ctx, "Invalid MAC address", log.Fields{"Addr": addr})
		return
	}
	copy(key[:], addr[0:6])
	drv := dn.AddDhcpVnet(session.GetNniVlans())
	drv.sessionLock.Lock()
	delete(drv.sessions, key)
	drv.sessionLock.Unlock()
}

// delDhcpSessions to delete dhcp sessions
func delDhcpSessions(addr net.HardwareAddr, outervlan of.VlanType, innervlan of.VlanType, sessionKey [MaxLenDhcpv6DUID]byte) {
	var key [6]byte
	if addr == nil || !NonZeroMacAddress(addr) {
		logger.Warnw(ctx, "Invalid MAC address", log.Fields{"Addr": addr})
		return
	}
	copy(key[:], addr[0:6])
	drv := dhcpNws.AddDhcpVnet(uint16(outervlan), uint16(innervlan))
	drv.sessionLock.Lock()
	delete(drv.sessions, key)
	delete(drv.sessionsv6, sessionKey)
	drv.sessionLock.Unlock()
	logger.Infow(ctx, "DHCP Sessions deleted", log.Fields{"MAC": addr})
}

// AddDhcp6Session to add dhcpv6 session
func (dn *DhcpNetworks) AddDhcp6Session(key [MaxLenDhcpv6DUID]byte, session IDhcpRelaySession) error {
	outerVlan, innerVlan := session.GetNniVlans()
	logger.Infow(ctx, "Adding Session", log.Fields{"outerVlan": outerVlan, "innerVlan": innerVlan, "Addr": key})
	drv := dn.AddDhcpVnet(outerVlan, innerVlan)
	drv.sessionLock.Lock()
	drv.sessionsv6[key] = session
	drv.sessionLock.Unlock()
	return nil
}

// DelDhcp6Session to delete dhcpv6 session
func (dn *DhcpNetworks) DelDhcp6Session(key [MaxLenDhcpv6DUID]byte, session IDhcpRelaySession) {
	outerVlan, innerVlan := session.GetNniVlans()
	logger.Infow(ctx, "Get Session", log.Fields{"OuterVLAN": outerVlan, "InnerVLAN": innerVlan, "Addr": key})
	drv := dn.GetDhcpVnet(outerVlan, innerVlan)
	drv.sessionLock.Lock()
	delete(drv.sessionsv6, key)
	drv.sessionLock.Unlock()
}

// GetDhcpSession to get dhcp session info
func (dn *DhcpNetworks) GetDhcpSession(outerVlan uint16, innerVlan uint16, addr net.HardwareAddr) (IDhcpRelaySession, error) {
	var key [6]byte
	if len(addr) != 6 {
		logger.Errorw(ctx, "Invalid MAC address", log.Fields{"Addr": addr})
		return nil, errors.New("Invalid MAC address")
	}
	copy(key[:], addr[0:6])
	drv := dn.AddDhcpVnet(outerVlan, innerVlan)
	drv.sessionLock.RLock()
	defer drv.sessionLock.RUnlock()
	if session, ok := drv.sessions[key]; ok {
		return session, nil
	}
	return nil, ErrSessionDoNotExist
}

// GetDhcp6Session to get Dhcp6Session
func (dn *DhcpNetworks) GetDhcp6Session(outerVlan uint16, innerVlan uint16, key [MaxLenDhcpv6DUID]byte) (IDhcpRelaySession, error) {
	logger.Infow(ctx, "Locating Session", log.Fields{"OuterVlan": outerVlan, "InnerVlan": innerVlan, "key": key})

	drv := dn.AddDhcpVnet(outerVlan, innerVlan)
	drv.sessionLock.RLock()
	defer drv.sessionLock.RUnlock()
	if session, ok := drv.sessionsv6[key]; ok {
		return session, nil
	}
	return nil, ErrSessionDoNotExist
}

// GetVlansFromPacket to get vlans from the packet
func GetVlansFromPacket(pkt gopacket.Packet) (innerVlan of.VlanType, outerVlan of.VlanType) {

	vlans := GetVlans(pkt)
	if len(vlans) == 1 {
		outerVlan = vlans[0]
		innerVlan = of.VlanNone
	} else if len(vlans) == 0 {
		innerVlan = of.VlanNone
		outerVlan = of.VlanNone
	} else {
		innerVlan = vlans[1]
		outerVlan = vlans[0]
	}
	return
}

// GetVnetForV4Nni to get vnet for v4 Nni
func GetVnetForV4Nni(dhcp *layers.DHCPv4, cvlan of.VlanType, svlan of.VlanType, pbit uint8) ([]*VoltPortVnet, error) {
	var err error
	var session IDhcpRelaySession
	var vpvList []*VoltPortVnet
	logger.Infow(ctx, "Mac Obtained MAC: ", log.Fields{"Addr": dhcp.ClientHWAddr})
	session, err = dhcpNws.GetDhcpSession(uint16(svlan), uint16(cvlan), dhcp.ClientHWAddr)

	if session != nil {
		vpv, ok := session.(*VoltPortVnet)
		logger.Infow(ctx, "Session Exist: VPV found", log.Fields{"VPV": vpv})
		if ok {
			vpvList = append(vpvList, vpv)
			return vpvList, nil
		}
	}

	if err == ErrSessionDoNotExist {
		//No DHCP Session found, find matching VPV to send the packet out
		logger.Info(ctx, "Session Doesnt Exist: Finding matching VPV")
		return GetApplication().GetVpvsForDsPkt(cvlan, svlan, dhcp.ClientHWAddr, pbit)
	}
	return nil, errors.New("The session retrieved of wrong type")
}

// GetVnetForV6Nni to get vnet for v6 Nni
func GetVnetForV6Nni(dhcp *layers.DHCPv6, cvlan of.VlanType, svlan of.VlanType,
	pbit uint8, clientMAC net.HardwareAddr) ([]*VoltPortVnet, net.HardwareAddr, error) {
	var err error
	var session IDhcpRelaySession
	var vpvList []*VoltPortVnet

	var sessionKey [MaxLenDhcpv6DUID]byte

	clientDuid, decodedDuid := getDhcpv6ClientDUID(dhcp)
	if clientDuid == nil || decodedDuid == nil {
		copy(sessionKey[:], clientMAC)
	} else {
		copy(sessionKey[:], clientDuid[0:])
		if decodedDuid.Type == layers.DHCPv6DUIDTypeLLT || decodedDuid.Type == layers.DHCPv6DUIDTypeLL {
			clientMAC = decodedDuid.LinkLayerAddress
		}
	}
	session, err = dhcpNws.GetDhcp6Session(uint16(svlan), uint16(cvlan), sessionKey)
	if session != nil {
		vpv, ok := session.(*VoltPortVnet)
		logger.Infow(ctx, "Session Exist: VPV found", log.Fields{"VPV": vpv})
		if ok {
			vpvList = append(vpvList, vpv)
			return vpvList, clientMAC, nil
		}
	}

	if err == ErrSessionDoNotExist {
		//No DHCP Session found, find matching VPV to send the packet out
		logger.Info(ctx, "Session Doesnt Exist: Finding matching VPV")
		vpvList, err := GetApplication().GetVpvsForDsPkt(cvlan, svlan, clientMAC, pbit)
		return vpvList, clientMAC, err
	}
	return nil, clientMAC, errors.New("The session retrieved of wrong type")
}

/*
// getDhcpv4ClientMacAddr to get mac address for dhcpv4 client
func getDhcpv4ClientMacAddr(pkt gopacket.Packet) net.HardwareAddr {
	dhcp := pkt.Layer(layers.LayerTypeDHCPv4).(*layers.DHCPv4)
	logger.Infow(ctx, "Mac Obtained v4: ", log.Fields{"Addr": dhcp.ClientHWAddr})
	return dhcp.ClientHWAddr
}

// getDhcpv6ClientMacAddr to get mac address for dhcpv6 client
func getDhcpv6ClientMacAddr(dhcpv6 *layers.DHCPv6) net.HardwareAddr {
	var cID layers.DHCPv6Option
	for _, option := range dhcpv6.Options {
		if option.Code == layers.DHCPv6OptClientID {
			cID = option
		}
	}
	duid := &layers.DHCPv6DUID{}

	//If cID is not found, DecodeFromBytes() returns error on empty cID
	if err := duid.DecodeFromBytes(cID.Data); err == nil {
		logger.Infow(ctx, "Mac Obtained v6: ", log.Fields{"Addr": duid.LinkLayerAddress, "Option": cID.String()})
		return duid.LinkLayerAddress
	}
	return nil
}*/

// getDhcpv6ClientDUID to get Dhcpv6 client DUID
func getDhcpv6ClientDUID(dhcpv6 *layers.DHCPv6) ([]byte, *layers.DHCPv6DUID) {

	for _, option := range dhcpv6.Options {
		logger.Debugw(ctx, "DHCPv6 Options", log.Fields{"option": option.Code})
		if option.Code == layers.DHCPv6OptClientID {
			duid := &layers.DHCPv6DUID{}
			err := duid.DecodeFromBytes(option.Data)
			if err == nil {
				logger.Infow(ctx, "ClientIdentifier", log.Fields{"DUID": duid, "Option": option.String()})
				duidLen := len(option.Data)
				if duidLen > 130 {
					duidLen = 130
				}
				return option.Data[0:duidLen], duid
			}
			logger.Errorw(ctx, "Client DUID decode failed", log.Fields{"error": err})
			break
		}
	}
	logger.Error(ctx, "Client DUID is not present in the packet")
	return nil, nil
}

// AddDhcpv4Option82 : DHCPv4 packet operations
// Addition of DHCP Option 82 which codes circuit-id and remote-id
// into the packet. This happens as the request is relayed to the
// DHCP servers on the NNI
func AddDhcpv4Option82(svc *VoltService, rID []byte, dhcpv4 *layers.DHCPv4) {
	//NOTE : both cID and rID should not be empty if this function is called
	cID := svc.GetCircuitID()
	var data []byte
	if len(cID) != 0 {
		data = append(data, 0x01)
		data = append(data, byte(len(cID)))
		data = append(data, cID...)
	}
	if len(rID) != 0 {
		data = append(data, 0x02)
		data = append(data, byte(len(rID)))
		data = append(data, rID...)
	}

	if svc.isDataRateAttrPresent() {
		minDrUs := util.Uint32ToByte(svc.MinDataRateUs)
		data = append(data, TYPEMINDATAUS)
		data = append(data, byte(len(minDrUs)))
		data = append(data, minDrUs...)

		minDrDs := util.Uint32ToByte(svc.MinDataRateDs)
		data = append(data, TYPEMINDATADS)
		data = append(data, byte(len(minDrDs)))
		data = append(data, minDrDs...)

		maxDrUs := util.Uint32ToByte(svc.MaxDataRateUs)
		data = append(data, TYPEMAXDATAUS)
		data = append(data, byte(len(maxDrUs)))
		data = append(data, maxDrUs...)

		maxDrDs := util.Uint32ToByte(svc.MaxDataRateDs)
		data = append(data, TYPEMAXDATADS)
		data = append(data, byte(len(maxDrDs)))
		data = append(data, maxDrDs...)
	}

	option := layers.NewDHCPOption(82, data)
	dhcpv4.Options = append(dhcpv4.Options, option)
}

// DelOption82 : Deletion of option 82 from the packet received on the NNI interface.
// Once the packet is received, the option 82 is stripped off and the
// packet is forwarded towards access
func DelOption82(dhcpv4 *layers.DHCPv4) {
	for index, option := range dhcpv4.Options {
		if option.Type == opt82 {
			dhcpv4.Options = append(dhcpv4.Options[0:index], dhcpv4.Options[index+1:]...)
			return
		}
	}
}

// DhcpMsgType returns the DHCP message type from the packet
func DhcpMsgType(dhcp *layers.DHCPv4) layers.DHCPMsgType {
	for _, option := range dhcp.Options {
		if option.Type == layers.DHCPOptMessageType {
			return layers.DHCPMsgType(option.Data[0])
		}
	}
	return layers.DHCPMsgTypeUnspecified
}

// GetIpv4Addr returns the IP address in the DHCP reply
func GetIpv4Addr(dhcp *layers.DHCPv4) (net.IP, int64) {
	var leaseTime uint32
	for _, opt := range dhcp.Options {
		if opt.Type == layers.DHCPOptLeaseTime {
			leaseTime = GetIPv4LeaseTime(opt)
		}
	}
	return dhcp.YourClientIP, int64(leaseTime)
}

//GetIPv4LeaseTime get ip lease time
func GetIPv4LeaseTime(opt layers.DHCPOption) uint32 {
	return uint32(opt.Data[0])<<24 | uint32(opt.Data[1])<<16 | uint32(opt.Data[2])<<8 | uint32(opt.Data[3])
}

// GetIpv6Addr returns the IPv6 address in the DHCPv6 reply
func GetIpv6Addr(dhcp6 *layers.DHCPv6) (net.IP, uint32) {
	var ipv6Addr net.IP
	var leaseTime uint32

	//Check for IANA allocation, if not present, then look for IAPD allocation
	if dhcp6.MsgType == layers.DHCPv6MsgTypeReply {
		ipv6Addr, leaseTime = GetIANAAddress(dhcp6)
		if ipv6Addr == nil {
			ipv6Addr, leaseTime = GetIAPDAddress(dhcp6)
		}
	}
	return ipv6Addr, leaseTime
}

// GetIANAAddress returns the IPv6 address in the DHCPv6 reply
func GetIANAAddress(dhcp6 *layers.DHCPv6) (net.IP, uint32) {
	var ipv6Addr net.IP
	var leaseTime uint32
	if dhcp6.MsgType == layers.DHCPv6MsgTypeReply {
		for _, o := range dhcp6.Options {
			if o.Code == layers.DHCPv6OptIANA {

				iana := &layers.DHCPv6IANA{}
				err := iana.DecodeFromBytes(o.Data)
				if err == nil {
					ipv6Addr = iana.IA.IPv6Addr
					leaseTime = iana.IA.ValidLifeTime
					logger.Debugw(ctx, "IPv6 Allocated", log.Fields{"IANA IPv6": ipv6Addr})
					return ipv6Addr, leaseTime
				}
				logger.Warn(ctx, "Decode of IANA Failed", log.Fields{"Reason": err.Error()})
				break
			}
		}
	}
	return nil, 0
}

// GetIAPDAddress returns the IPv6 address in the DHCPv6 reply
func GetIAPDAddress(dhcp6 *layers.DHCPv6) (net.IP, uint32) {
	var ipv6Addr net.IP
	var leaseTime uint32
	if dhcp6.MsgType == layers.DHCPv6MsgTypeReply {
		for _, o := range dhcp6.Options {
			if o.Code == layers.DHCPv6OptIAPD {

				iapd := &layers.DHCPv6IAPD{}
				if err := iapd.DecodeFromBytes(o.Data); err == nil {
					ipv6Addr = iapd.PD.Prefix
					leaseTime = iapd.PD.ValidLifeTime
					logger.Debugw(ctx, "IPv6 Allocated", log.Fields{"IAPD IPv6": ipv6Addr})
					break
				} else {
					logger.Warn(ctx, "Decode of IAPD Failed", log.Fields{"Reason": err.Error()})
					break
				}
			}
		}
	}
	return ipv6Addr, leaseTime
}

// ProcessDsDhcpv4Packet : DHCPv4 packet processor functions
// This function processes DS DHCP packet received on the NNI port.
// The services are attached to the access ports. Thus, the DHCP
// session is derived from the list of DHCP sessions stored in the
// common map. The key for retrieval includes the VLAN tags in the
// the packet and the MAC address of the client.
func (va *VoltApplication) ProcessDsDhcpv4Packet(device string, port string, pkt gopacket.Packet) {

	// Retrieve the layers to build the outgoing packet. It is not
	// possible to add/remove layers to the existing packet and thus
	// the lyayers are extracted to build the outgoing packet
	eth := pkt.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
	ip := pkt.Layer(layers.LayerTypeIPv4).(*layers.IPv4)
	udp := pkt.Layer(layers.LayerTypeUDP).(*layers.UDP)
	dhcp4 := pkt.Layer(layers.LayerTypeDHCPv4).(*layers.DHCPv4)
	msgType := DhcpMsgType(dhcp4)

	// Need to locate the service from the packet alone as the services
	// are not attached to NNI port. The service is stored on DHCP relay
	// application
	logger.Infow(ctx, "Processing Southbound DS DHCPv4 packet", log.Fields{"Port": port, "Type": msgType})

	// Retrieve the priority and drop eligible flags from the
	// packet received
	var priority uint8
	var dsPbit uint8
	var dropEligible bool
	dot1ql := pkt.Layer(layers.LayerTypeDot1Q)
	if dot1ql != nil {
		dot1q := dot1ql.(*layers.Dot1Q)
		priority = dot1q.Priority
		dropEligible = dot1q.DropEligible
	}

	pktInnerlan, pktOuterlan := GetVlansFromPacket(pkt)
	vpvList, _ := GetVnetForV4Nni(dhcp4, pktInnerlan, pktOuterlan, priority)
	if len(vpvList) == 0 {
		logger.Warn(ctx, "VNET couldn't be found for NNI")
		return
	}

	// The DHCP option 82, if it exists is removed from the packet
	DelOption82(dhcp4)
	ipAddr, leaseTime := GetIpv4Addr(dhcp4)

	for _, vpv := range vpvList {
		dsPbit = vpv.GetRemarkedPriority(priority)
		// Raise DHCP ACK/NCK indication
		if vpv.DhcpRelay {
			// Inform dhcp response information to dhcp server handler
			dhcpResponseReceived(uint16(vpv.CVlan), uint16(vpv.SVlan))
			// Process the Ack/Nack to track to state of the IP layer of the connection
			if msgType == layers.DHCPMsgTypeAck || msgType == layers.DHCPMsgTypeNak {
				// Install DS HSIA flows after DHCP ACK.
				if msgType == layers.DHCPMsgTypeAck {
					// Voltha will push US and DS HSIA flow on receivng the DS HSIA
					// flow installation request, VGC to update US HSIA flow with leanrt MAC.
					// separate go rotuine is spawned to avoid drop of ACK packet
					// as HSIA flows will be deleted if new MAC is learnt.
					go vpv.SetMacAddr(dhcp4.ClientHWAddr)
				}
				vpv.DhcpResultInd(dhcp4)

			}
			raiseDHCPv4Indication(msgType, vpv, dhcp4.ClientHWAddr, ipAddr, dsPbit, device, leaseTime)
		}

		// Create the outgoing bufer and set the checksum in the packet
		buff := gopacket.NewSerializeBuffer()
		if err := udp.SetNetworkLayerForChecksum(ip); err != nil {
			logger.Error(ctx, "Error in setting checksum")
			return
		}
		opts := gopacket.SerializeOptions{
			FixLengths:       true,
			ComputeChecksums: true,
		}

		cTagType := layers.EthernetTypeIPv4
		eth.EthernetType = layers.EthernetTypeDot1Q

		var pktLayers []gopacket.SerializableLayer
		pktLayers = append(pktLayers, eth)

		var qVlans []of.VlanType
		var qVlanLayers []gopacket.SerializableLayer

		if vpv.AllowTransparent {
			vlanThreshold := 2
			// In case of ONU_CVLAN or OLT_SVLAN, the DS pkts have single configured vlan
			// In case of ONU_CVLAN_OLT_SVLAN or OLT_CVLAN_OLT_SVLAN, the DS pkts have 2 configured vlan
			// Based on that, the no. of vlans should be ignored to get only transparent vlans
			if vpv.VlanControl == ONUCVlan || vpv.VlanControl == OLTSVlan || vpv.VlanControl == None {
				vlanThreshold = 1
			}
			nxtLayer := layers.EthernetTypeDot1Q
			if vlans := GetVlans(pkt); len(vlans) > vlanThreshold {
				qVlans = vlans[vlanThreshold:]
				cTagType = layers.EthernetTypeDot1Q
			}
			for i, qVlan := range qVlans {
				vlan := uint16(qVlan)
				if i == (len(qVlans) - 1) {
					nxtLayer = layers.EthernetTypeIPv4
				}
				qdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: vlan, DropEligible: dropEligible, Type: nxtLayer}
				qVlanLayers = append(qVlanLayers, qdot1q)
			}
		}
		switch vpv.VlanControl {
		case ONUCVlanOLTSVlan:
			cdot1q := &layers.Dot1Q{Priority: dsPbit, VLANIdentifier: uint16(vpv.CVlan), DropEligible: dropEligible, Type: cTagType}
			pktLayers = append(pktLayers, cdot1q)
		case ONUCVlan,
			None:
			sdot1q := &layers.Dot1Q{Priority: dsPbit, VLANIdentifier: uint16(vpv.SVlan), DropEligible: dropEligible, Type: cTagType}
			pktLayers = append(pktLayers, sdot1q)
		case OLTCVlanOLTSVlan,
			OLTSVlan:
			udot1q := &layers.Dot1Q{Priority: dsPbit, VLANIdentifier: uint16(vpv.UniVlan), DropEligible: dropEligible, Type: cTagType}
			pktLayers = append(pktLayers, udot1q)
		default:
			logger.Errorw(ctx, "Invalid Vlan Control Option", log.Fields{"Value": vpv.VlanControl})
		}

		pktLayers = append(pktLayers, qVlanLayers...)
		pktLayers = append(pktLayers, ip)
		pktLayers = append(pktLayers, udp)
		pktLayers = append(pktLayers, dhcp4)
		logger.Debugw(ctx, "Layers Count", log.Fields{"Count": len(pktLayers)})
		if err := gopacket.SerializeMultiLayers(buff, opts, pktLayers); err != nil {
			logger.Errorw(ctx, "Packet Serialization Failed", log.Fields{"Reason": err.Error()})
			return
		}

		if err := cntlr.GetController().PacketOutReq(device, vpv.Port, port, buff.Bytes(), false); err != nil {
			logger.Errorw(ctx, "PacketOutReq Failed",  log.Fields{"Error" : err})
		}
	}
}

// raiseDHCPv4Indication process DHCPv4 packet and raise indication
func raiseDHCPv4Indication(msgType layers.DHCPMsgType, vpv *VoltPortVnet, smac net.HardwareAddr,
	ip net.IP, pktPbit uint8, device string, leaseTime int64) {

	logger.Debugw(ctx, "Processing Dhcpv4 packet", log.Fields{"ethsrcMac": smac.String(),
		"MacLearningInVPV": vpv.MacLearning, "MacConfigured": vpv.MacAddr, "dhcpType": msgType,
		"vlanPriority": pktPbit, "VPVLearntMac": vpv.LearntMacAddr})

	matchServiceAndRaiseInd := func(key, value interface{}) bool {
		// walk through all svcs under vpv and match pbit with packet.
		svc := value.(*VoltService)

		if svc.IsPbitExist(of.PbitType(pktPbit)) {
			logger.Debugw(ctx, "Matching Pbit found in service config", log.Fields{"ServiceName": svc.Name, "Pbit": pktPbit})
			return false
		}
		return true
	}

	switch msgType {
	case layers.DHCPMsgTypeDiscover, layers.DHCPMsgTypeRequest:
		if msgType == layers.DHCPMsgTypeDiscover {
			vpv.SetDhcpState(DhcpRelayStateDiscover)
		} else if msgType == layers.DHCPMsgTypeRequest {
			vpv.SetDhcpState(DhcpRelayStateRequest)
		}
	// Reset learnt mac address in case of DHCPv4 release
	case layers.DHCPMsgTypeRelease:
		vpv.LearntMacAddr, _ = net.ParseMAC("00:00:00:00:00:00")
		vpv.services.Range(matchServiceAndRaiseInd)
		vpv.SetDhcpState(DhcpRelayStateRelease)

	case layers.DHCPMsgTypeAck, layers.DHCPMsgTypeNak:
		vpv.services.Range(matchServiceAndRaiseInd)
		if msgType == layers.DHCPMsgTypeAck {
			vpv.SetDhcpState(DhcpRelayStateAck)
		} else if msgType == layers.DHCPMsgTypeNak {
			vpv.SetDhcpState(DhcpRelayStateNAK)
		}
	case layers.DHCPMsgTypeOffer:
		vpv.SetDhcpState(DhcpRelayStateOffer)
	}
}

// raiseDHCPv6Indication process DHCPv6 packet and raise indication
func raiseDHCPv6Indication(msgType layers.DHCPv6MsgType, vpv *VoltPortVnet,
	smac net.HardwareAddr, ip net.IP, pktPbit uint8, device string, leaseTime uint32) {

	logger.Debugw(ctx, "Processing DHCPv6 packet", log.Fields{"dhcpType": msgType,
		"vlanPriority": pktPbit, "dhcpClientMac": smac.String(),
		"MacLearningInVPV": vpv.MacLearning, "MacConfigured": vpv.MacAddr,
		"VPVLearntMac": vpv.LearntMacAddr})

	matchServiceAndRaiseInd := func(key, value interface{}) bool {
		svc := value.(*VoltService)
		if svc.IsPbitExist(of.PbitType(pktPbit)) {
			logger.Debugw(ctx, "Matching Pbit found in service config", log.Fields{"ServiceName": svc.Name, "Pbit": pktPbit})
			return false
		}
		return true
	}

	switch msgType {
	case layers.DHCPv6MsgTypeSolicit:
		vpv.SetDhcpv6State(Dhcpv6RelayStateSolicit)
	// Reset learnt mac address in case of DHCPv6 release
	case layers.DHCPv6MsgTypeRelease:
		vpv.LearntMacAddr, _ = net.ParseMAC("00:00:00:00:00:00")
		vpv.services.Range(matchServiceAndRaiseInd)
		vpv.SetDhcpv6State(Dhcpv6RelayStateRelease)

	case layers.DHCPv6MsgTypeReply:
		vpv.services.Range(matchServiceAndRaiseInd)
		vpv.SetDhcpv6State(Dhcpv6RelayStateReply)
	}
}

// ProcessUsDhcpv4Packet : The US DHCPv4 packet is identified the DHCP OP in the packet. A request is considered upstream
// and the service associated with the packet is located by the port and VLANs in the packet
func (va *VoltApplication) ProcessUsDhcpv4Packet(device string, port string, pkt gopacket.Packet) {
	// We received the packet on an access port and the service for the packet can be
	// gotten from the port and the packet
	vpv, svc := va.GetVnetFromPkt(device, port, pkt)
	if vpv == nil {
		logger.Warn(ctx, "VNET couldn't be found from packet")
		return
	}

	outport, _ := va.GetNniPort(device)
	if outport == "" || outport == "0" {
		logger.Errorw(ctx, "NNI Port not found for device. Dropping Packet", log.Fields{"NNI": outport})
		return
	}

	// Extract the layers in the packet to prepare the outgoing packet
	// We use the layers to build the outgoing packet from scratch as
	// the packet received can't be modified to add/remove layers
	eth := pkt.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
	ip := pkt.Layer(layers.LayerTypeIPv4).(*layers.IPv4)
	udp := pkt.Layer(layers.LayerTypeUDP).(*layers.UDP)
	dhcp4 := pkt.Layer(layers.LayerTypeDHCPv4).(*layers.DHCPv4)
	msgType := DhcpMsgType(dhcp4)
	logger.Infow(ctx, "Processing Southbound US DHCPv4 packet", log.Fields{"Device": device, "Port": port, "Type": msgType})

	// Learn the 8021P values from the packet received
	var priority uint8
	var dropEligible bool
	dot1ql := pkt.Layer(layers.LayerTypeDot1Q)
	if dot1ql != nil {
		dot1q := dot1ql.(*layers.Dot1Q)
		priority = dot1q.Priority
		dropEligible = dot1q.DropEligible
	}
	// If this is the first message in the DHCP sequence, the service
	// is added to the DHCP relay application. The reply packets locate
	// the associated service/session from the relay application.
	if msgType == layers.DHCPMsgTypeDiscover || msgType == layers.DHCPMsgTypeRequest {
		if err := dhcpNws.AddDhcpSession(pkt, vpv); err != nil {
			logger.Errorw(ctx, "Adding dhcp session failed", log.Fields{"Error": err})
		}
	}

	// Raise mac-learnt(DHCP Discover) indication when mac learning is enabled and learnt mac
	// is not same as received mac address. If mac learning disabled, we have mac address in the
	// service configuration. Hence mac learnt indication is not raised
	// Reset learnt mac address in case of DHCP release and raise the indication
	if vpv.DhcpRelay {
		// If this is the first message in the DHCP sequence, the service
		// is added to the DHCP relay application. The reply packets locate
		// the associated service/session from the relay application.
		// DS HSIA flows will be added after DHCP ACK .
		if msgType == layers.DHCPMsgTypeDiscover || msgType == layers.DHCPMsgTypeRequest {
			if !util.MacAddrsMatch(vpv.MacAddr, dhcp4.ClientHWAddr) {
				// MAC is different and relearning is disabled.
				if NonZeroMacAddress(vpv.MacAddr) && vpv.MacLearning == Learn {
					// update learnt mac for debug purpose
					vpv.LearntMacAddr = dhcp4.ClientHWAddr
					vpv.WriteToDb()
					logger.Warnw(ctx, "Dropping the packet Mac relearn is disabled",
						log.Fields{"vpv.MacAddr": vpv.MacAddr, "LearntMac": dhcp4.ClientHWAddr})
					return
				}
				expectedPort := va.GetMacInPortMap(dhcp4.ClientHWAddr)
				if expectedPort != "" && expectedPort != vpv.Port {
					logger.Errorw(ctx, "mac-learnt-from-different-port-ignoring-dhcp-message", log.Fields{"MsgType": msgType, "ExpectedPort": expectedPort, "ReceivedPort": vpv.Port, "LearntMacAdrr": vpv.MacAddr, "NewMacAdrr": dhcp4.ClientHWAddr.String()})
					return
				}
			}
		}
		raiseDHCPv4Indication(msgType, vpv, dhcp4.ClientHWAddr, vpv.Ipv4Addr, priority, device, 0)

		// Check IsOption82Disabled flag in configuration. if true(disabled), do not add option82 into dhcpv4 header.
		// Remote id can be custom or mac address.
		// If remote id is custom, then add service will carry the remote id
		// If remote id is mac address, and if mac is configured, then add service will carry the remote id
		// If remote id is mac address, in mac learning case, then mac has to be taken from dhcp packet
		if !svc.IsOption82Disabled {
			var remoteID []byte
			if svc.RemoteIDType == string(MACAddress) {
				remoteID = []byte((dhcp4.ClientHWAddr).String())
			} else if svc.RemoteID != nil {
				remoteID = svc.RemoteID
			}
			AddDhcpv4Option82(svc, remoteID, dhcp4)
		}
	}

	buff := gopacket.NewSerializeBuffer()
	if err := udp.SetNetworkLayerForChecksum(ip); err != nil {
		logger.Error(ctx, "Error in setting checksum")
		return
	}
	opts := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}

	cTagType := layers.EthernetTypeIPv4
	outerVlan, innerVlan := vpv.GetNniVlans()
	logger.Debugw(ctx, "Vnet Vlans", log.Fields{"Svlan": outerVlan, "Cvlan": innerVlan})
	eth.EthernetType = vpv.SVlanTpid

	var pktLayers []gopacket.SerializableLayer
	pktLayers = append(pktLayers, eth)

	var qVlans []of.VlanType
	var qVlanLayers []gopacket.SerializableLayer

	if vpv.AllowTransparent {
		nxtLayer := layers.EthernetTypeDot1Q
		if vlans := GetVlans(pkt); len(vlans) > 1 {
			qVlans = vlans[1:]
			logger.Debugw(ctx, "Q Vlans", log.Fields{"Vlan List": qVlans})
			cTagType = layers.EthernetTypeDot1Q
		}
		for i, qVlan := range qVlans {
			vlan := uint16(qVlan)
			if i == (len(qVlans) - 1) {
				nxtLayer = layers.EthernetTypeIPv4
			}
			qdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: vlan, DropEligible: dropEligible, Type: nxtLayer}
			qVlanLayers = append(qVlanLayers, qdot1q)
		}
	}
	switch vpv.VlanControl {
	case ONUCVlanOLTSVlan,
		OLTCVlanOLTSVlan:
		sdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: outerVlan, DropEligible: dropEligible, Type: layers.EthernetTypeDot1Q}
		pktLayers = append(pktLayers, sdot1q)
		cdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: innerVlan, DropEligible: dropEligible, Type: cTagType}
		pktLayers = append(pktLayers, cdot1q)
	case ONUCVlan,
		OLTSVlan,
		None:
		cdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: outerVlan, DropEligible: dropEligible, Type: cTagType}
		pktLayers = append(pktLayers, cdot1q)
	default:
		logger.Errorw(ctx, "Invalid Vlan Control Option", log.Fields{"Value": vpv.VlanControl})
	}

	pktLayers = append(pktLayers, qVlanLayers...)
	pktLayers = append(pktLayers, ip)
	pktLayers = append(pktLayers, udp)
	pktLayers = append(pktLayers, dhcp4)
	logger.Debugw(ctx, "Layers Count", log.Fields{"Count": len(pktLayers)})
	if err := gopacket.SerializeMultiLayers(buff, opts, pktLayers); err != nil {
		return
	}

	// Now the packet constructed is output towards the switch to be emitted on
	// the NNI port
	if err := cntlr.GetController().PacketOutReq(device, outport, port, buff.Bytes(), false); err != nil {
		logger.Errorw(ctx, "PacketOutReq Failed",  log.Fields{"Error" : err})
	}
	if vpv.DhcpRelay {
		// Inform dhcp request information to dhcp server handler
		dhcpRequestReceived(uint16(vpv.CVlan), uint16(vpv.SVlan), eth.SrcMAC.String())
	}
}

// ProcessUDP4Packet : CallBack function registered with application to handle DHCP packetIn
func ProcessUDP4Packet(device string, port string, pkt gopacket.Packet) {
	GetApplication().ProcessUDP4Packet(device, port, pkt)
}

// ProcessUDP4Packet : The packet is a UDP packet and currently only DHCP relay application is supported
// We determine the packet direction and process it based on the direction
func (va *VoltApplication) ProcessUDP4Packet(device string, port string, pkt gopacket.Packet) {
	// Currently DHCP is the only application supported by the application
	// We check for DHCP before proceeding futher. In future, this could be
	// based on registration and the callbacks
	dhcpl := pkt.Layer(layers.LayerTypeDHCPv4)
	if dhcpl == nil {
		return
	}
	//logger.Debugw(ctx, "Received Packet In", log.Fields{"Pkt": hex.EncodeToString(pkt.Data())})
	dhcp4 := pkt.Layer(layers.LayerTypeDHCPv4).(*layers.DHCPv4)
	if dhcp4.Operation == layers.DHCPOpRequest {
		// This is treated as an upstream packet in the VOLT application
		// as VOLT serves access subscribers who use DHCP to acquire IP
		// address and these packets go upstream to the network
		va.ProcessUsDhcpv4Packet(device, port, pkt)
	} else {
		// This is a downstream packet
		va.ProcessDsDhcpv4Packet(device, port, pkt)
	}

}

// ProcessUDP6Packet : CallBack function registered with application to handle DHCPv6 packetIn
func ProcessUDP6Packet(device string, port string, pkt gopacket.Packet) {
	GetApplication().ProcessUDP6Packet(device, port, pkt)
}

// ProcessUDP6Packet : As a LDRA node, we expect to see only RelayReply from the DHCP server and we always
// pack the received request and send it to the server as a RelayForward message
// We expect to see Solicit, Request in the most normal cases. Before the lease expires
// we should also see Renew. However, we should always pack the US message by adding
// additional option that identifies to the server that the DHCP packet is forwarded
// by an LDRA node.
func (va *VoltApplication) ProcessUDP6Packet(device string, port string, pkt gopacket.Packet) []byte {
	dhcpl := pkt.Layer(layers.LayerTypeDHCPv6)
	if dhcpl == nil {
		return nil
	}
	logger.Infow(ctx, "Processing DHCPv6 packet", log.Fields{"Port": port})
	dhcpv6 := dhcpl.(*layers.DHCPv6)
	switch dhcpv6.MsgType {
	case layers.DHCPv6MsgTypeSolicit, layers.DHCPv6MsgTypeRequest, layers.DHCPv6MsgTypeRenew,
		layers.DHCPv6MsgTypeRelease, layers.DHCPv6MsgTypeRebind, layers.DHCPv6MsgTypeInformationRequest,
		layers.DHCPv6MsgTypeDecline:
		va.ProcessUsDhcpv6Packet(device, port, pkt)
	case layers.DHCPv6MsgTypeAdvertise, layers.DHCPv6MsgTypeConfirm, layers.DHCPv6MsgTypeReconfigure:
		logger.Warnw(ctx, "SouthBound DHCPv6 DS Messages Expected For a Relay Agent", log.Fields{"Type": dhcpv6.MsgType})
	case layers.DHCPv6MsgTypeRelayForward:
		logger.Warn(ctx, "As the first DHCPv6 Relay Agent, Unexpected Relay Forward")
	case layers.DHCPv6MsgTypeRelayReply:
		// We received a response from the server
		va.ProcessDsDhcpv6Packet(device, port, pkt)
	}
	return nil
}

// GetRelayReplyBytes to get relay reply bytes
func GetRelayReplyBytes(dhcp6 *layers.DHCPv6) []byte {
	for _, o := range dhcp6.Options {
		logger.Infow(ctx, "Received Option", log.Fields{"Code": o.Code})
		if o.Code == layers.DHCPv6OptRelayMessage {
			return o.Data
		}
	}
	return nil
}

// BuildRelayFwd to build forward relay
func BuildRelayFwd(paddr net.IP, intfID []byte, remoteID []byte, payload []byte, isOption82Disabled bool, dhcpRelay bool) *layers.DHCPv6 {
	dhcp6 := &layers.DHCPv6{MsgType: layers.DHCPv6MsgTypeRelayForward, LinkAddr: net.ParseIP("::"), PeerAddr: []byte(paddr)}
	dhcp6.Options = append(dhcp6.Options, layers.NewDHCPv6Option(layers.DHCPv6OptRelayMessage, payload))
	// Check IsOption82Disabled flag in configuration. if true(disabled), do not add remoteID and circuitID into dhcpv6 header.
	if dhcpRelay {
		if !isOption82Disabled {
			remote := &layers.DHCPv6RemoteId{RemoteId: remoteID}
			if len(remoteID) != 0 {
				dhcp6.Options = append(dhcp6.Options, layers.NewDHCPv6Option(layers.DHCPv6OptRemoteID, remote.Encode()))
			}
			if len(intfID) != 0 {
				intf := &layers.DHCPv6IntfId{Data: intfID}
				dhcp6.Options = append(dhcp6.Options, layers.NewDHCPv6Option(layers.DHCPv6OptInterfaceID, intf.Encode()))
			}
		}
	}
	return dhcp6
}

// ProcessUsDhcpv6Packet to rpocess upstream DHCPv6 packet
func (va *VoltApplication) ProcessUsDhcpv6Packet(device string, port string, pkt gopacket.Packet) {
	// We received the packet on an access port and the service for the packet can be
	// gotten from the port and the packet
	logger.Infow(ctx, "Processing Southbound US DHCPv6 packet", log.Fields{"Port": port})
	logger.Debugw(ctx, "Packet IN", log.Fields{"Pkt": hex.EncodeToString(pkt.Data())})
	vpv, svc := va.GetVnetFromPkt(device, port, pkt)
	if vpv == nil {
		logger.Warn(ctx, "VNET couldn't be found from packet")
		return
	}

	outport, _ := va.GetNniPort(device)
	if outport == "" || outport == "0" {
		logger.Errorw(ctx, "NNI Port not found for device. Dropping Packet", log.Fields{"NNI": outport})
		return
	}

	// Extract the layers in the packet to prepare the outgoing packet
	// We use the layers to build the outgoing packet from scratch as
	// the packet received can't be modified to add/remove layers
	eth := pkt.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
	ip := pkt.Layer(layers.LayerTypeIPv6).(*layers.IPv6)
	udp := pkt.Layer(layers.LayerTypeUDP).(*layers.UDP)
	idhcp6 := pkt.Layer(layers.LayerTypeDHCPv6).(*layers.DHCPv6)

	// Remote id can be custom or mac address.
	// If remote id is custom, then add service will carry the remote id
	// If remote id is mac address, and if mac is configured, then add service will carry the remote id
	// If remote id is mac address, in mac learning case, then mac has to be taken from dhcp packet
	var remoteID []byte
	if svc.RemoteIDType == string(MACAddress) {
		remoteID = []byte((eth.SrcMAC).String())
	} else if svc.RemoteID != nil {
		remoteID = svc.RemoteID
	}
	dhcp6 := BuildRelayFwd(ip.SrcIP, svc.GetCircuitID(), remoteID, udp.Payload, svc.IsOption82Disabled, vpv.DhcpRelay)

	var sourceMac = eth.SrcMAC
	var sessionKey [MaxLenDhcpv6DUID]byte

	clientDuid, decodedDuid := getDhcpv6ClientDUID(idhcp6)
	if clientDuid == nil || decodedDuid == nil {
		copy(sessionKey[:], eth.SrcMAC)
	} else {
		copy(sessionKey[:], clientDuid[0:])
		if decodedDuid.Type == layers.DHCPv6DUIDTypeLLT || decodedDuid.Type == layers.DHCPv6DUIDTypeLL {
			sourceMac = decodedDuid.LinkLayerAddress
		}
	}
	// Learn the 8021P values from the packet received
	var priority uint8
	var dropEligible bool
	dot1ql := pkt.Layer(layers.LayerTypeDot1Q)
	if dot1ql != nil {
		dot1q := dot1ql.(*layers.Dot1Q)
		priority = dot1q.Priority
		dropEligible = dot1q.DropEligible
	}
	if idhcp6.MsgType == layers.DHCPv6MsgTypeSolicit {
		if err := dhcpNws.AddDhcp6Session(sessionKey, vpv); err != nil {
			logger.Errorw(ctx, "Adding dhcpv6 session failed", log.Fields{"Error": err})
		}
		vpv.DHCPv6DUID = sessionKey
	}

	// Raise mac-learnt(DHCPv6MsgTypeSolicit) indication when mac learning is enabled and learnt mac
	// is not same as received mac address. If mac learning disabled, we have mac address in the
	// service configuration. Hence mac learnt indication is not raised
	if vpv.DhcpRelay {
		if idhcp6.MsgType == layers.DHCPv6MsgTypeSolicit {
			if !util.MacAddrsMatch(vpv.MacAddr, sourceMac) {
				// MAC is different and relearning is disabled.
				if NonZeroMacAddress(vpv.MacAddr) && vpv.MacLearning == Learn {
					// update learnt mac for debug purpose
					vpv.LearntMacAddr = sourceMac
					vpv.WriteToDb()
					logger.Warnw(ctx, "Dropping the packet Mac relearn is disabled",
						log.Fields{"vpv.MacAddr": vpv.MacAddr, "LearntMac": sourceMac})
					return
				}
				expectedPort := va.GetMacInPortMap(sourceMac)
				if expectedPort != "" && expectedPort != vpv.Port {
					logger.Errorw(ctx, "mac-learnt-from-different-port-ignoring-dhcp-message", log.Fields{"MsgType": idhcp6.MsgType, "ExpectedPort": expectedPort, "ReceivedPort": vpv.Port, "LearntMacAdrr": vpv.MacAddr, "NewMacAdrr": sourceMac.String()})
					return
				}
			}
		}
		raiseDHCPv6Indication(idhcp6.MsgType, vpv, sourceMac, vpv.Ipv6Addr, priority, device, 0)
	}

	// Create the buffer and the encode options for the outgoing packet
	buff := gopacket.NewSerializeBuffer()
	if err := udp.SetNetworkLayerForChecksum(ip); err != nil {
		logger.Error(ctx, "Error in setting checksum")
		return
	}
	opts := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}

	cTagType := layers.EthernetTypeIPv6
	outerVlan, innerVlan := vpv.GetNniVlans()
	eth.EthernetType = vpv.SVlanTpid

	var pktLayers []gopacket.SerializableLayer
	pktLayers = append(pktLayers, eth)

	var qVlans []of.VlanType
	var qVlanLayers []gopacket.SerializableLayer

	if vpv.AllowTransparent {
		nxtLayer := layers.EthernetTypeDot1Q
		if vlans := GetVlans(pkt); len(vlans) > 1 {
			qVlans = vlans[1:]
			cTagType = layers.EthernetTypeDot1Q
		}
		for i, qVlan := range qVlans {
			vlan := uint16(qVlan)
			if i == (len(qVlans) - 1) {
				nxtLayer = layers.EthernetTypeIPv6
			}
			qdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: vlan, DropEligible: dropEligible, Type: nxtLayer}
			qVlanLayers = append(qVlanLayers, qdot1q)
		}

	}
	switch vpv.VlanControl {
	case ONUCVlanOLTSVlan,
		OLTCVlanOLTSVlan:
		sdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: outerVlan, DropEligible: dropEligible, Type: layers.EthernetTypeDot1Q}
		pktLayers = append(pktLayers, sdot1q)
		cdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: innerVlan, DropEligible: dropEligible, Type: cTagType}
		pktLayers = append(pktLayers, cdot1q)
	case ONUCVlan,
		OLTSVlan,
		None:
		cdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: outerVlan, DropEligible: dropEligible, Type: cTagType}
		pktLayers = append(pktLayers, cdot1q)
	default:
		logger.Errorw(ctx, "Invalid Vlan Control Option", log.Fields{"Value": vpv.VlanControl})
	}

	pktLayers = append(pktLayers, qVlanLayers...)
	pktLayers = append(pktLayers, ip)
	pktLayers = append(pktLayers, udp)
	pktLayers = append(pktLayers, dhcp6)
	logger.Debugw(ctx, "Layers Count", log.Fields{"Count": len(pktLayers)})
	if err := gopacket.SerializeMultiLayers(buff, opts, pktLayers); err != nil {
		return
	}
	// Now the packet constructed is output towards the switch to be emitted on
	// the NNI port
	if err := cntlr.GetController().PacketOutReq(device, outport, port, buff.Bytes(), false); err != nil {
		logger.Errorw(ctx, "PacketOutReq Failed",  log.Fields{"Error" : err})
	}
	if vpv.DhcpRelay {
		// Inform dhcp request information to dhcp server handler
		dhcpRequestReceived(uint16(vpv.CVlan), uint16(vpv.SVlan), eth.SrcMAC.String())
	}
}

// GetDhcpv6 to get dhcpv6 info
func GetDhcpv6(payload []byte) (*layers.DHCPv6, error) {
	pkt := gopacket.NewPacket(payload, layers.LayerTypeDHCPv6, gopacket.Default)
	if dl := pkt.Layer(layers.LayerTypeDHCPv6); dl != nil {
		if dhcp6, ok := dl.(*layers.DHCPv6); ok {
			return dhcp6, nil
		}
	}
	return nil, errors.New("Failed to decode DHCPv6")
}

// ProcessDsDhcpv6Packet to process downstream dhcpv6 packet
func (va *VoltApplication) ProcessDsDhcpv6Packet(device string, port string, pkt gopacket.Packet) {
	logger.Infow(ctx, "Processing Southbound DS DHCPv6 packet", log.Fields{"Port": port})
	logger.Debugw(ctx, "Packet IN", log.Fields{"Pkt": hex.EncodeToString(pkt.Data())})

	// Retrieve the layers to build the outgoing packet. It is not
	// possible to add/remove layers to the existing packet and thus
	// the lyayers are extracted to build the outgoing packet
	// The DHCP layer is handled differently. The Relay-Reply option
	// of DHCP is extracted and is made the UDP payload.
	eth := pkt.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
	ip := pkt.Layer(layers.LayerTypeIPv6).(*layers.IPv6)
	udp := pkt.Layer(layers.LayerTypeUDP).(*layers.UDP)
	idhcp6 := pkt.Layer(layers.LayerTypeDHCPv6).(*layers.DHCPv6)
	//var dhcp6 *layers.DHCPv6
	var payload []byte
	if payload = GetRelayReplyBytes(idhcp6); payload == nil {
		logger.Warn(ctx, "Didn't Receive RelayMessage IE")
		return
	}

	dhcp6, err := GetDhcpv6(payload)
	if err != nil {
		logger.Warnw(ctx, "DHCPv6 Decode Failed", log.Fields{"Reason": err.Error()})
		return
	}

	// Learn the 8021P values from the packet received
	var priority uint8
	var dsPbit uint8
	var dropEligible bool
	dot1ql := pkt.Layer(layers.LayerTypeDot1Q)
	if dot1ql != nil {
		dot1q := dot1ql.(*layers.Dot1Q)
		priority = dot1q.Priority
		dropEligible = dot1q.DropEligible
	}

	pktInnerlan, pktOuterlan := GetVlansFromPacket(pkt)
	vpvList, clientMac, err := GetVnetForV6Nni(dhcp6, pktInnerlan, pktOuterlan, priority, eth.DstMAC)
	if len(vpvList) == 0 {
		logger.Warnw(ctx, "VNET couldn't be found for NNI", log.Fields{"Reason": err})
		return
	}

	ipv6Addr, leaseTime := GetIpv6Addr(dhcp6)

	for _, vpv := range vpvList {

		dsPbit = vpv.GetRemarkedPriority(priority)
		// Raise DHCPv6 Reply indication
		if vpv.DhcpRelay {
			// Inform dhcp response information to dhcp server handler
			dhcpResponseReceived(uint16(vpv.CVlan), uint16(vpv.SVlan))

			if dhcp6.MsgType == layers.DHCPv6MsgTypeReply && ipv6Addr != nil {
				// separate go rotuine is spawned to avoid drop of ACK packet
				// as HSIA flows will be deleted if new MAC is learnt.
				if len(vpvList) == 1 {
					go vpv.SetMacAddr(clientMac)
				}
				vpv.Dhcpv6ResultInd(ipv6Addr, leaseTime)
			}
			raiseDHCPv6Indication(dhcp6.MsgType, vpv, clientMac, ipv6Addr, dsPbit, device, leaseTime)
		}

		//Replace dst Port value to 546
		udp.DstPort = 546
		logger.Infow(ctx, "Packet Out UDP Port..", log.Fields{"UDP": udp, "Port": udp.DstPort})

		// Create the buffer and the encode options for the outgoing packet
		buff := gopacket.NewSerializeBuffer()
		if err := udp.SetNetworkLayerForChecksum(ip); err != nil {
			logger.Error(ctx, "Error in setting checksum")
			return
		}
		opts := gopacket.SerializeOptions{
			FixLengths:       true,
			ComputeChecksums: true,
		}

		cTagType := layers.EthernetTypeIPv6
		eth.EthernetType = layers.EthernetTypeDot1Q

		var pktLayers []gopacket.SerializableLayer
		pktLayers = append(pktLayers, eth)

		var qVlans []of.VlanType
		var qVlanLayers []gopacket.SerializableLayer

		if vpv.AllowTransparent {
			vlanThreshold := 2
			// In case of ONU_CVLAN or OLT_SVLAN, the DS pkts have single configured vlan
			// In case of ONU_CVLAN_OLT_SVLAN or OLT_CVLAN_OLT_SVLAN, the DS pkts have 2 configured vlan
			// Based on that, the no. of vlans should be ignored to get only transparent vlans
			if vpv.VlanControl == ONUCVlan || vpv.VlanControl == OLTSVlan || vpv.VlanControl == None {
				vlanThreshold = 1
			}
			nxtLayer := layers.EthernetTypeDot1Q
			if vlans := GetVlans(pkt); len(vlans) > vlanThreshold {
				qVlans = vlans[vlanThreshold:]
				cTagType = layers.EthernetTypeDot1Q
			}
			for i, qVlan := range qVlans {
				vlan := uint16(qVlan)
				if i == (len(qVlans) - 1) {
					nxtLayer = layers.EthernetTypeIPv6
				}
				qdot1q := &layers.Dot1Q{Priority: priority, VLANIdentifier: vlan, DropEligible: dropEligible, Type: nxtLayer}
				qVlanLayers = append(qVlanLayers, qdot1q)
			}

		}
		switch vpv.VlanControl {
		case ONUCVlanOLTSVlan:
			cdot1q := &layers.Dot1Q{Priority: dsPbit, VLANIdentifier: uint16(vpv.CVlan), DropEligible: dropEligible, Type: cTagType}
			pktLayers = append(pktLayers, cdot1q)
		case ONUCVlan,
			None:
			sdot1q := &layers.Dot1Q{Priority: dsPbit, VLANIdentifier: uint16(vpv.SVlan), DropEligible: dropEligible, Type: cTagType}
			pktLayers = append(pktLayers, sdot1q)
		case OLTCVlanOLTSVlan,
			OLTSVlan:
			udot1q := &layers.Dot1Q{Priority: dsPbit, VLANIdentifier: uint16(vpv.UniVlan), DropEligible: dropEligible, Type: cTagType}
			pktLayers = append(pktLayers, udot1q)
		default:
			logger.Errorw(ctx, "Invalid Vlan Control Option", log.Fields{"Value": vpv.VlanControl})
		}

		pktLayers = append(pktLayers, qVlanLayers...)
		pktLayers = append(pktLayers, ip)
		pktLayers = append(pktLayers, udp)
		pktLayers = append(pktLayers, dhcp6)
		logger.Debugw(ctx, "Layers Count", log.Fields{"Count": len(pktLayers)})
		if err := gopacket.SerializeMultiLayers(buff, opts, pktLayers); err != nil {
			logger.Errorw(ctx, "Packet Serialization Failed", log.Fields{"Reason": err.Error()})
			return
		}

		if err := cntlr.GetController().PacketOutReq(device, vpv.Port, port, buff.Bytes(), false); err != nil {
			logger.Errorw(ctx, "PacketOutReq Failed", log.Fields{"Reason": err.Error()})
		}
	}
}

// The DHCP relay application is maintained within the structures below
var dhcpNws *DhcpNetworks

func init() {
	dhcpNws = NewDhcpNetworks()
}
