blob: 702044f4b49d8e76d5c4c7bfc6f01af8b63b8e2c [file] [log] [blame]
Jakub Grajciar07363a42020-04-02 10:02:17 +02001/*
2 *------------------------------------------------------------------
3 * Copyright (c) 2020 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *------------------------------------------------------------------
16 */
17
18package memif
19
20// WritePacket writes one packet to the shared memory and
21// returns the number of bytes written
22func (q *Queue) WritePacket(pkt []byte) int {
23 var mask int = q.ring.size - 1
24 var slot int
25 var nFree uint16
26 var packetBufferSize int = int(q.i.run.PacketBufferSize)
27
28 if q.i.args.IsMaster {
29 slot = q.readTail()
30 nFree = uint16(q.readHead() - slot)
31 } else {
32 slot = q.readHead()
33 nFree = uint16(q.ring.size - slot + q.readTail())
34 }
35
36 if nFree == 0 {
37 q.interrupt()
38 return 0
39 }
40
41 // copy descriptor from shm
42 desc := newDescBuf()
43 q.getDescBuf(slot&mask, desc)
44 // reset flags
45 desc.setFlags(0)
46 // reset length
47 if q.i.args.IsMaster {
48 packetBufferSize = desc.getLength()
49 }
50 desc.setLength(0)
51 offset := desc.getOffset()
52
53 // write packet into memif buffer
54 n := copy(q.i.regions[desc.getRegion()].data[offset:offset+packetBufferSize], pkt[:])
55 desc.setLength(n)
56 for n < len(pkt) {
57 nFree--
58 if nFree == 0 {
59 q.interrupt()
60 return 0
61 }
62 desc.setFlags(descFlagNext)
63 q.putDescBuf(slot&mask, desc)
64 slot++
65
66 // copy descriptor from shm
67 q.getDescBuf(slot&mask, desc)
68 // reset flags
69 desc.setFlags(0)
70 // reset length
71 if q.i.args.IsMaster {
72 packetBufferSize = desc.getLength()
73 }
74 desc.setLength(0)
75 offset := desc.getOffset()
76
77 tmp := copy(q.i.regions[desc.getRegion()].data[offset:offset+packetBufferSize], pkt[:])
78 desc.setLength(tmp)
79 n += tmp
80 }
81
82 // copy descriptor to shm
83 q.putDescBuf(slot&mask, desc)
84 slot++
85
86 if q.i.args.IsMaster {
87 q.writeTail(slot)
88 } else {
89 q.writeHead(slot)
90 }
91
92 q.interrupt()
93
94 return n
95}