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
+}