AAA Emulation & BBSim Containerization

VOL-1154, VOL-1168, VOL-1273

Change-Id: Ib0fbbaec897f633601976e8636c218f42375bedd
diff --git a/core/io_worker.go b/core/io_worker.go
new file mode 100644
index 0000000..a535869
--- /dev/null
+++ b/core/io_worker.go
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2018-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 core
+
+import (
+	"errors"
+	"github.com/google/gopacket"
+	"github.com/google/gopacket/layers"
+	"github.com/google/gopacket/pcap"
+	"log"
+	"net"
+)
+
+func RecvWorker(io *Ioinfo, handler *pcap.Handle, r chan Packet) {
+	log.Printf("recvWorker runs. handler: %v", *handler)
+	packetSource := gopacket.NewPacketSource(handler, handler.LinkType())
+	for packet := range packetSource.Packets() {
+		log.Printf("recv packet from IF: %v \n", *handler)
+		//log.Println(packet.Dump())
+		pkt := Packet{}
+		pkt.Info = io
+		pkt.Pkt = packet
+		r <- pkt
+	}
+}
+
+func SendUni(handle *pcap.Handle, packet gopacket.Packet) {
+	handle.WritePacketData(packet.Data())
+	log.Printf("send packet to UNI-IF: %v \n", *handle)
+	//log.Println(packet.Dump())
+}
+
+func SendNni(handle *pcap.Handle, packet gopacket.Packet) {
+	handle.WritePacketData(packet.Data())
+	log.Printf("send packet to NNI-IF: %v \n", *handle)
+	//log.Println(packet.Dump())
+}
+
+func PopVLAN(pkt gopacket.Packet) (gopacket.Packet, uint16, error) {
+	if layer := getDot1QLayer(pkt); layer != nil {
+		if eth := getEthernetLayer(pkt); eth != nil {
+			ethernetLayer := &layers.Ethernet{
+				SrcMAC:       eth.SrcMAC,
+				DstMAC:       eth.DstMAC,
+				EthernetType: layer.Type,
+			}
+			buffer := gopacket.NewSerializeBuffer()
+			gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{},
+				ethernetLayer,
+				gopacket.Payload(layer.Payload),
+			)
+			retpkt := gopacket.NewPacket(
+				buffer.Bytes(),
+				layers.LayerTypeEthernet,
+				gopacket.Default,
+			)
+			vid := uint16(4095 & layer.VLANIdentifier)
+			log.Printf("Pop the 802.1Q header (VID: %d)", vid)
+			return retpkt, vid, nil
+		}
+	}
+	//return pkt, 1, nil
+	return nil, 0, errors.New("failed to pop vlan")
+}
+
+func PushVLAN(pkt gopacket.Packet, vid uint16) (gopacket.Packet, error) {
+	if eth := getEthernetLayer(pkt); eth != nil {
+		ethernetLayer := &layers.Ethernet{
+			SrcMAC:       eth.SrcMAC,
+			DstMAC:       eth.DstMAC,
+			EthernetType: 0x8100,
+		}
+		dot1qLayer := &layers.Dot1Q{
+			Type:           eth.EthernetType,
+			VLANIdentifier: uint16(vid),
+		}
+
+		buffer := gopacket.NewSerializeBuffer()
+		gopacket.SerializeLayers(
+			buffer,
+			gopacket.SerializeOptions{
+				FixLengths: false,
+			},
+			ethernetLayer,
+			dot1qLayer,
+			gopacket.Payload(eth.Payload),
+		)
+		ret := gopacket.NewPacket(
+			buffer.Bytes(),
+			layers.LayerTypeEthernet,
+			gopacket.Default,
+		)
+		log.Printf("Push the 802.1Q header (VID: %d)", vid)
+		return ret, nil
+	}
+	return nil, errors.New("failed to push vlan")
+}
+
+func getEthernetLayer(pkt gopacket.Packet) *layers.Ethernet {
+	eth := &layers.Ethernet{}
+	if ethLayer := pkt.Layer(layers.LayerTypeEthernet); ethLayer != nil {
+		eth, _ = ethLayer.(*layers.Ethernet)
+	}
+	return eth
+}
+func getDot1QLayer(pkt gopacket.Packet) (dot1q *layers.Dot1Q) {
+	if dot1qLayer := pkt.Layer(layers.LayerTypeDot1Q); dot1qLayer != nil {
+		dot1q = dot1qLayer.(*layers.Dot1Q)
+	}
+	return dot1q
+}
+
+func getMacAddress(ifName string) net.HardwareAddr {
+	var err error
+	var netIf *net.Interface
+	var hwAddr net.HardwareAddr
+	if netIf, err = net.InterfaceByName(ifName); err == nil {
+		hwAddr = netIf.HardwareAddr
+	}
+	return hwAddr
+}