Skip to content

Commit c4e1737

Browse files
rvicheryak-dhananjay
authored andcommitted
AK-46144 use an interface to handle packet burst (#3)
+ accept an interface for NewPacketHandle makes it easy to unit tests functions which use NewPacketHandle without interacting with the lower level memif structure. + used in alkiranet/csn/services/memif-receiver service
1 parent 2609544 commit c4e1737

File tree

3 files changed

+50
-34
lines changed

3 files changed

+50
-34
lines changed

extras/libmemif/README.md

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ to the compiler.
1515

1616
For example, to install C-libmemif system-wide into the standard
1717
locations, execute:
18+
1819
```
1920
$ git clone https://gerrit.fd.io/r/vpp
2021
$ cd vpp/extras/libmemif
@@ -30,6 +31,7 @@ Package **libmemif** is not part of the **GoVPP** core and as such it is
3031
not included in the [make build](../../Makefile) target.
3132
Instead, it has its own target in the [top-level Makefile](../../Makefile)
3233
used to build the attached examples with the adapter:
34+
3335
```
3436
$ make extras
3537
```
@@ -61,6 +63,7 @@ structure representing the underlying memif interface.
6163

6264
Callbacks are optional and can be shared across multiple memif instances.
6365
Available callbacks are:
66+
6467
1. **OnConnect**: called when the connection is established.
6568
By the time the callback is called, the Rx/Tx queues are initialized
6669
and ready for data transmission. Interrupt channels are also
@@ -105,7 +108,7 @@ Do not touch memif after it was closed, let garbage collector to remove
105108
the `Memif` instance. In the end, `Cleanup()` will also ensure that all
106109
active memif interfaces are closed before the cleanup finalizes.
107110

108-
To use libmemif with `google/gopacket`, simply call `Memif.NewPacketHandle()`
111+
To use libmemif with `google/gopacket`, simply call `libmemif.NewPacketHandle()`
109112
to create `google/gopacket/PacketDataSource` from memif queue. After this you
110113
can use gopacket API to read from `MemifPacketHandle` as normal. You can pass
111114
optional `rxCount` when creating the packet handle and then when reading data,
@@ -121,46 +124,48 @@ The examples can be found in the subdirectory [examples](./examples).
121124

122125
#### Raw data (libmemif <-> libmemif)
123126

124-
*raw-data* is a basic example showing how to create a memif interface,
127+
_raw-data_ is a basic example showing how to create a memif interface,
125128
handle events through callbacks and perform Rx/Tx of raw data. Before
126129
handling an actual packet it is important to understand the skeleton
127130
of libmemif-based applications.
128131

129132
Since VPP expects proper packet data, it is not very useful to connect
130-
*raw-data* example with VPP, even though it will work, since all
133+
_raw-data_ example with VPP, even though it will work, since all
131134
the received data will get dropped on the VPP side.
132135

133136
To create a connection of two raw-data instances, start two processes
134137
concurrently in an arbitrary order:
135-
- *master* memif:
136-
```
137-
$ cd extras/libmemif/examples/raw-data
138-
$ ./raw-data
139-
```
140-
- *slave* memif:
141-
```
142-
$ cd extras/libmemif/examples/raw-data
143-
$ ./raw-data --slave
144-
```
138+
139+
- _master_ memif:
140+
```
141+
$ cd extras/libmemif/examples/raw-data
142+
$ ./raw-data
143+
```
144+
- _slave_ memif:
145+
```
146+
$ cd extras/libmemif/examples/raw-data
147+
$ ./raw-data --slave
148+
```
145149

146150
Every 3 seconds both sides send 3 raw-data packets to the opposite end
147151
through each of the 3 queues. The received packets are printed to stdout.
148152

149-
Stop an instance of *raw-data* with an interrupt signal (^C).
153+
Stop an instance of _raw-data_ with an interrupt signal (^C).
150154

151155
#### Jumbo Frames Raw data (libmemif <-> libmemif)
152156

153-
*jumbo-frames* is simple example how to send larger and larger jumbo
154-
packets with libmemif adapter. This is simple copy of *raw-data* but with
157+
_jumbo-frames_ is simple example how to send larger and larger jumbo
158+
packets with libmemif adapter. This is simple copy of _raw-data_ but with
155159
sending larger packets, so for more information read its code and documentation.
156160

157161
#### ICMP Responder
158162

159-
*icmp-responder* is a simple example showing how to answer APR and ICMP
163+
_icmp-responder_ is a simple example showing how to answer APR and ICMP
160164
echo requests through a memif interface. Package `google/gopacket` is
161165
used to decode and construct packets.
162166

163167
The appropriate VPP configuration for the opposite memif is:
168+
164169
```
165170
vpp$ create memif socket id 1 filename /tmp/icmp-responder-example
166171
vpp$ create interface memif id 1 socket-id 1 slave secret secret no-zero-copy
@@ -169,22 +174,25 @@ vpp$ set int ip address memif1/1 192.168.1.2/24
169174
```
170175

171176
To start the example, simply type:
177+
172178
```
173179
root$ ./icmp-responder
174180
```
175181

176-
*icmp-responder* needs to be run as root so that it can access the socket
182+
_icmp-responder_ needs to be run as root so that it can access the socket
177183
created by VPP.
178184

179185
Normally, the memif interface is in the master mode. Pass CLI flag `--slave`
180186
to create memif in the slave mode:
187+
181188
```
182189
root$ ./icmp-responder --slave
183190
```
184191

185192
Don't forget to put the opposite memif into the master mode in that case.
186193

187194
To verify the connection, run:
195+
188196
```
189197
vpp$ ping 192.168.1.1
190198
64 bytes from 192.168.1.1: icmp_seq=2 ttl=255 time=.6974 ms
@@ -197,20 +205,22 @@ vpp$ sh ip arp
197205
Time IP4 Flags Ethernet Interface
198206
68.5648 192.168.1.1 D aa:aa:aa:aa:aa:aa memif0/1
199207
```
200-
*Note*: it is expected that the first ping is shown as lost.
201-
It was actually converted to an ARP request. This is a VPP
202-
specific feature common to all interface types.
208+
209+
_Note_: it is expected that the first ping is shown as lost.
210+
It was actually converted to an ARP request. This is a VPP
211+
specific feature common to all interface types.
203212

204213
Stop the example with an interrupt signal (^C).
205214

206215
#### GoPacket ICMP Responder
207216

208-
*gopacket* is a simple example showing how to answer APR and ICMP echo
217+
_gopacket_ is a simple example showing how to answer APR and ICMP echo
209218
requests through a memif interface. This example is mostly identical
210219
to icmp-responder example, but it is using MemifPacketHandle API to
211220
read and write packets using gopacket API.
212221

213222
The appropriate VPP configuration for the opposite memif is:
223+
214224
```
215225
vpp$ create memif socket id 1 filename /tmp/gopacket-example
216226
vpp$ create interface memif id 1 socket-id 1 slave secret secret no-zero-copy
@@ -219,6 +229,7 @@ vpp$ set int ip address memif1/1 192.168.1.2/24
219229
```
220230

221231
To start the example, simply type:
232+
222233
```
223234
root$ ./gopacket
224235
```
@@ -228,13 +239,15 @@ created by VPP.
228239

229240
Normally, the memif interface is in the master mode. Pass CLI flag "--slave"
230241
to create memif in the slave mode:
242+
231243
```
232244
root$ ./gopacket --slave
233245
```
234246

235247
Don't forget to put the opposite memif into the master mode in that case.
236248

237249
To verify the connection, run:
250+
238251
```
239252
vpp$ ping 192.168.1.1
240253
64 bytes from 192.168.1.1: icmp_seq=2 ttl=255 time=.6974 ms
@@ -248,8 +261,8 @@ Time IP4 Flags Ethernet Interface
248261
68.5648 192.168.1.1 D aa:aa:aa:aa:aa:aa memif0/1
249262
```
250263

251-
*Note*: it is expected that the first ping is shown as lost.
252-
It was actually converted to an ARP request. This is a VPP
253-
specific feature common to all interface types.
264+
_Note_: it is expected that the first ping is shown as lost.
265+
It was actually converted to an ARP request. This is a VPP
266+
specific feature common to all interface types.
254267

255268
Stop the example with an interrupt signal (^C).

extras/libmemif/examples/gopacket/gopacket.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,6 @@ package main
4747
import (
4848
"errors"
4949
"fmt"
50-
"github.com/alkiranet/govpp/extras/libmemif"
51-
"github.com/google/gopacket"
52-
"github.com/google/gopacket/layers"
5350
"io"
5451
"net"
5552
"os"
@@ -97,7 +94,7 @@ func OnConnect(memif *libmemif.Memif) (err error) {
9794
continue
9895
}
9996

100-
go CreateInterruptCallback(memif.NewPacketHandle(queue.QueueID, 10), ch, OnInterrupt)
97+
go CreateInterruptCallback(libmemif.NewPacketHandle(memif, queue.QueueID, 10), ch, OnInterrupt)
10198
}
10299

103100
return

extras/libmemif/packethandle.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,14 @@ type memoizedPacket struct {
2626
ci gopacket.CaptureInfo
2727
}
2828

29+
// BurstHandler is an interface that implements methods for reading and writing packets in bursts.
30+
type BurstHandler interface {
31+
RxBurst(queueID uint8, count uint16) (packets []RawPacketData, err error)
32+
TxBurst(queueID uint8, packets []RawPacketData) (count uint16, err error)
33+
}
34+
2935
type MemifPacketHandle struct {
30-
memif *Memif
36+
handler BurstHandler
3137
queueId uint8
3238
rxCount uint16
3339

@@ -43,13 +49,13 @@ type MemifPacketHandle struct {
4349

4450
// Create new GoPacket packet handle from libmemif queue. rxCount determines how many packets will be read
4551
// at once, minimum value is 1
46-
func (memif *Memif) NewPacketHandle(queueId uint8, rxCount uint16) *MemifPacketHandle {
52+
func NewPacketHandle(burstHandler BurstHandler, queueId uint8, rxCount uint16) *MemifPacketHandle {
4753
if rxCount == 0 {
4854
rxCount = 1
4955
}
5056

5157
return &MemifPacketHandle{
52-
memif: memif,
58+
handler: burstHandler,
5359
queueId: queueId,
5460
rxCount: rxCount,
5561
}
@@ -70,7 +76,7 @@ func (handle *MemifPacketHandle) ReadPacketData() (data []byte, ci gopacket.Capt
7076
queueLen := len(handle.packetQueue)
7177

7278
if queueLen == 0 {
73-
packets, burstErr := handle.memif.RxBurst(handle.queueId, handle.rxCount)
79+
packets, burstErr := handle.handler.RxBurst(handle.queueId, handle.rxCount)
7480
packetsLen := len(packets)
7581

7682
if burstErr != nil {
@@ -118,7 +124,7 @@ func (handle *MemifPacketHandle) WritePacketData(data []byte) (err error) {
118124
return
119125
}
120126

121-
count, err := handle.memif.TxBurst(handle.queueId, []RawPacketData{data})
127+
count, err := handle.handler.TxBurst(handle.queueId, []RawPacketData{data})
122128

123129
if err != nil {
124130
return

0 commit comments

Comments
 (0)