libmemif for Golang is build on the top of the original, C-written
libmemif library using `cgo`. It is therefore necessary to have C-libmemif
-header files and the library itself installed in locations known
+header files, and the library itself installed in locations known
to the compiler.
For example, to install C-libmemif system-wide into the standard
```
$ git clone https://gerrit.fd.io/r/vpp
$ cd vpp/extras/libmemif
-$ make install
+$ mkdir build
+$ cd build
+$ cmake ..
+$ sudo make install
```
### Build
**libmemif** was designed for a maximum possible performance. Packets
are sent and received in bulks, rather than one-by-one, using
`Memif.TxBurst(queueID, packets)` and `Memif.RxBurst(queueID, count)`,
-respectively. Memif connection can consists of multiple queues in both
+respectively. Memif connection can consist of multiple queues in both
directions. A queue is one-directional wait-free ring buffer.
It is the unit of parallelism for data transmission. The maximum possible
lock-free granularity is therefore one go routine for one queue.
the `Memif` instance. In the end, `Cleanup()` will also ensure that all
active memif interfaces are closed before the cleanup finalizes.
+To use libmemif with `google/gopacket`, simply call `Memif.NewPacketHandle()`
+to create `google/gopacket/PacketDataSource` from memif queue. After this you
+can use gopacket API to read from `MemifPacketHandle` as normal. You can pass
+optional `rxCount` when creating the packet handle and then when reading data,
+handle will try to read more packets at once and cache them for next iteration.
+Handle also includes convenience method `MemifPacketHandle.WritePacketData()`
+that is simply calling 1 `Memif.TxBurst()` for provided data.
+
### Examples
**Go-libmemif** ships with two simple examples demonstrating the usage
*raw-data* is a basic example showing how to create a memif interface,
handle events through callbacks and perform Rx/Tx of raw data. Before
-handling an actual packets it is important to understand the skeleton
+handling an actual packet it is important to understand the skeleton
of libmemif-based applications.
Since VPP expects proper packet data, it is not very useful to connect
Stop an instance of *raw-data* with an interrupt signal (^C).
+#### Jumbo Frames Raw data (libmemif <-> libmemif)
+
+*jumbo-frames* is simple example how to send larger and larger jumbo
+packets with libmemif adapter. This is simple copy of *raw-data* but with
+sending larger packets, so for more information read its code and documentation.
+
#### ICMP Responder
*icmp-responder* is a simple example showing how to answer APR and ICMP
The appropriate VPP configuration for the opposite memif is:
```
-vpp$ create memif id 1 socket /tmp/icmp-responder-example slave secret secret
-vpp$ set int state memif0/1 up
-vpp$ set int ip address memif0/1 192.168.1.2/24
+vpp$ create memif socket id 1 filename /tmp/icmp-responder-example
+vpp$ create interface memif id 1 socket-id 1 slave secret secret no-zero-copy
+vpp$ set int state memif1/1 up
+vpp$ set int ip address memif1/1 192.168.1.2/24
```
To start the example, simply type:
It was actually converted to an ARP request. This is a VPP
specific feature common to all interface types.
-Stop the example with an interrupt signal (^C).
\ No newline at end of file
+Stop the example with an interrupt signal (^C).
+
+#### GoPacket ICMP Responder
+
+*gopacket* is a simple example showing how to answer APR and ICMP echo
+requests through a memif interface. This example is mostly identical
+to icmp-responder example, but it is using MemifPacketHandle API to
+read and write packets using gopacket API.
+
+The appropriate VPP configuration for the opposite memif is:
+```
+vpp$ create memif socket id 1 filename /tmp/gopacket-example
+vpp$ create interface memif id 1 socket-id 1 slave secret secret no-zero-copy
+vpp$ set int state memif1/1 up
+vpp$ set int ip address memif1/1 192.168.1.2/24
+```
+
+To start the example, simply type:
+```
+root$ ./gopacket
+```
+
+gopacket needs to be run as root so that it can access the socket
+created by VPP.
+
+Normally, the memif interface is in the master mode. Pass CLI flag "--slave"
+to create memif in the slave mode:
+```
+root$ ./gopacket --slave
+```
+
+Don't forget to put the opposite memif into the master mode in that case.
+
+To verify the connection, run:
+```
+vpp$ ping 192.168.1.1
+64 bytes from 192.168.1.1: icmp_seq=2 ttl=255 time=.6974 ms
+64 bytes from 192.168.1.1: icmp_seq=3 ttl=255 time=.6310 ms
+64 bytes from 192.168.1.1: icmp_seq=4 ttl=255 time=1.0350 ms
+64 bytes from 192.168.1.1: icmp_seq=5 ttl=255 time=.5359 ms
+
+Statistics: 5 sent, 4 received, 20% packet loss
+vpp$ sh ip arp
+Time IP4 Flags Ethernet Interface
+68.5648 192.168.1.1 D aa:aa:aa:aa:aa:aa memif0/1
+```
+
+*Note*: it is expected that the first ping is shown as lost.
+ It was actually converted to an ARP request. This is a VPP
+ specific feature common to all interface types.
+
+Stop the example with an interrupt signal (^C).