1 // Copyright (c) 2017 Cisco and/or its affiliates.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at:
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
18 "github.com/google/gopacket"
24 type memoizedPacket struct {
26 ci gopacket.CaptureInfo
29 type MemifPacketHandle struct {
34 // Used for caching packets when larger rxburst is called
35 packetQueue []*memoizedPacket
37 // Used for synchronization of read/write calls
44 // Create new GoPacket packet handle from libmemif queue. rxCount determines how many packets will be read
45 // at once, minimum value is 1
46 func (memif *Memif) NewPacketHandle(queueId uint8, rxCount uint16) *MemifPacketHandle {
51 return &MemifPacketHandle{
58 // Reads packet data from memif in bursts, based on previously configured rxCount parameterer. Then caches the
59 // resulting packets and returns them 1 by 1 from this method until queue is empty then tries to call new rx burst
60 // to read more data. If no data is returned, io.EOF error is thrown and caller should stop reading.
61 func (handle *MemifPacketHandle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
63 defer handle.readMu.Unlock()
70 queueLen := len(handle.packetQueue)
73 packets, burstErr := handle.memif.RxBurst(handle.queueId, handle.rxCount)
74 packetsLen := len(packets)
86 handle.packetQueue = make([]*memoizedPacket, packetsLen)
88 for i, packet := range packets {
89 packetLen := len(packet)
91 handle.packetQueue[i] = &memoizedPacket{
93 ci: gopacket.CaptureInfo{
94 Timestamp: time.Now(),
95 CaptureLength: packetLen,
102 packet := handle.packetQueue[0]
103 handle.packetQueue = handle.packetQueue[1:]
110 // Writes packet data to memif in burst of 1 packet. In case no packet is sent, this method throws io.EOF error and
111 // called should stop trying to write packets.
112 func (handle *MemifPacketHandle) WritePacketData(data []byte) (err error) {
113 handle.writeMu.Lock()
114 defer handle.writeMu.Unlock()
121 count, err := handle.memif.TxBurst(handle.queueId, []RawPacketData{data})
134 // Waits for all read and write operations to finish and then prevents more from occurring. Handle can be closed only
135 // once and then can never be opened again.
136 func (handle *MemifPacketHandle) Close() {
137 handle.closeMu.Lock()
138 defer handle.closeMu.Unlock()
140 // wait for packet reader to stop
142 defer handle.readMu.Unlock()
144 // wait for packet writer to stop
145 handle.writeMu.Lock()
146 defer handle.writeMu.Unlock()
148 // stop reading and writing