VOL-1839: PacketOut now checks for different types of q-in-q and modifies appropriately

Removing the innerVLAN is erroneous if the outervlan is type 802.1ad (88a8)
(bbsim tester uses this)

Fixing this revealed that the ethernet library being used cannot handle
802.1q 802.1q double tagged packets.  Given the need to manually fix
these packets the library was removed as it was no longer needed.

Verified on hardware onu/olt and bbsim

Change-Id: Ifd065234e6a1fe40dc7d916140a8bcd5f9bb5d33
diff --git a/adaptercore/device_handler.go b/adaptercore/device_handler.go
index b686c8d..e00f626 100644
--- a/adaptercore/device_handler.go
+++ b/adaptercore/device_handler.go
@@ -19,6 +19,7 @@
 
 import (
 	"context"
+	"encoding/hex"
 	"errors"
 	"fmt"
 	"io"
@@ -32,7 +33,6 @@
 
 	"github.com/gogo/protobuf/proto"
 	"github.com/golang/protobuf/ptypes"
-	"github.com/mdlayher/ethernet"
 	com "github.com/opencord/voltha-go/adapters/common"
 	"github.com/opencord/voltha-go/common/log"
 	rsrcMgr "github.com/opencord/voltha-openolt-adapter/adaptercore/resourcemanager"
@@ -1065,52 +1065,40 @@
 
 // PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
 func (dh *DeviceHandler) PacketOut(egressPortNo int, packet *of.OfpPacketOut) error {
-	log.Debugw("PacketOut", log.Fields{"deviceID": dh.deviceID, "egress_port_no": egressPortNo, "pkt-length": len(packet.Data)})
-	var etherFrame ethernet.Frame
-	err := (&etherFrame).UnmarshalBinary(packet.Data)
-	if err != nil {
-		log.Errorw("Failed to unmarshal into ethernet frame", log.Fields{"err": err, "pkt-length": len(packet.Data)})
-		return err
-	}
-	log.Debugw("Ethernet Frame", log.Fields{"Frame": etherFrame})
+	log.Debugw("incoming-packet-out", log.Fields{"deviceID": dh.deviceID, "egress_port_no": egressPortNo,
+		"pkt-length": len(packet.Data), "packetData": hex.EncodeToString(packet.Data)})
+
 	egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
 	if egressPortType == voltha.Port_ETHERNET_UNI {
-		if etherFrame.VLAN != nil { // If double tag, remove the outer tag
-			nextEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
-			if nextEthType == 0x8100 {
-				etherFrame.VLAN = nil
-				packet.Data, err = etherFrame.MarshalBinary()
-				if err != nil {
-					log.Errorw("failed to marshal frame:", log.Fields{"err": err, "etherFrame": etherFrame})
-					return err
-				}
-				if err := (&etherFrame).UnmarshalBinary(packet.Data); err != nil {
-					log.Errorw("failed to unmarshal frame:", log.Fields{"err": err, "packetData": packet.Data})
-					return err
-				}
-				log.Debug("Double tagged packet , removed outer vlan", log.Fields{"New frame": etherFrame})
+		outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
+		innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
+		if outerEthType == 0x88a8 || outerEthType == 0x8100 {
+			if innerEthType == 0x8100 {
+				// q-in-q 802.1ad or 802.1q double tagged packet.
+				// slice out the outer tag.
+				packet.Data = append(packet.Data[:12], packet.Data[16:]...)
+				log.Debugw("packet-now-single-tagged", log.Fields{"packetData": hex.EncodeToString(packet.Data)})
 			}
 		}
 		intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
 		onuID := OnuIDFromPortNum(uint32(egressPortNo))
-		uniID := UniIDFromPortNum(uint32(egressPortNo))
-		/*gemPortId, err := dh.flowMgr.GetPacketOutGemPortId(intfID, onuID, uint32(egress_port_no))
-		  if err != nil{
-		      log.Errorw("Error while getting gemport to packet-out",log.Fields{"error": err})
-		      return err
-		  }*/
+		uniID := uint32(egressPortNo)
 		onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), Pkt: packet.Data}
-		log.Debug("sending-packet-to-ONU", log.Fields{"egress_port_no": egressPortNo, "IntfId": intfID, "onuID": onuID,
-			"uniID": uniID, "packet": packet.Data})
+
+		log.Debugw("sending-packet-to-onu", log.Fields{"egress_port_no": egressPortNo, "IntfId": intfID, "onuID": onuID,
+			"uniID": uniID, "packet": hex.EncodeToString(packet.Data)})
+
 		if _, err := dh.Client.OnuPacketOut(context.Background(), &onuPkt); err != nil {
 			log.Errorw("Error while sending packet-out to ONU", log.Fields{"error": err})
 			return err
 		}
 	} else if egressPortType == voltha.Port_ETHERNET_NNI {
 		uplinkPkt := oop.UplinkPacket{IntfId: IntfIDFromNniPortNum(uint32(egressPortNo)), Pkt: packet.Data}
-		log.Debug("sending-packet-to-uplink", log.Fields{"uplink_pkt": uplinkPkt})
+
+		log.Debugw("sending-packet-to-nni", log.Fields{"uplink_pkt": uplinkPkt, "packet": hex.EncodeToString(packet.Data)})
+
 		if _, err := dh.Client.UplinkPacketOut(context.Background(), &uplinkPkt); err != nil {
-			log.Errorw("Error while sending packet-out to uplink", log.Fields{"error": err})
+			log.Errorw("Error while sending packet-out to NNI", log.Fields{"error": err})
 			return err
 		}
 	} else {