From 8c3f04816a8fd23a5eabde1b36cb2471e06229bc Mon Sep 17 00:00:00 2001 From: Vladimir Lavor Date: Tue, 4 Aug 2020 12:37:25 +0200 Subject: Update libmemif Change-Id: I5db0460f375c9e34bc09170a310d52e1a619ed34 Signed-off-by: Vladimir Lavor --- extras/libmemif/README.md | 13 +++++----- extras/libmemif/adapter.go | 29 +++++++++++++++------- extras/libmemif/examples/gopacket/gopacket.go | 6 ++--- .../examples/icmp-responder/icmp-responder.go | 6 ++--- extras/libmemif/packethandle.go | 6 ++--- 5 files changed, 36 insertions(+), 24 deletions(-) diff --git a/extras/libmemif/README.md b/extras/libmemif/README.md index d663fd2..a8807a3 100644 --- a/extras/libmemif/README.md +++ b/extras/libmemif/README.md @@ -9,7 +9,7 @@ labels `Go-libmemif` and `C-libmemif` are used in the documentation. 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 @@ -17,9 +17,10 @@ locations, execute: ``` $ git clone https://gerrit.fd.io/r/vpp $ cd vpp/extras/libmemif -$ ./bootstrap -$ ./configure -$ make install +$ mkdir build +$ cd build +$ cmake .. +$ sudo make install ``` ### Build @@ -77,7 +78,7 @@ Available callbacks are: **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. @@ -121,7 +122,7 @@ The examples can be found in the subdirectory [examples](./examples). *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 diff --git a/extras/libmemif/adapter.go b/extras/libmemif/adapter.go index 1bb9229..0cee589 100644 --- a/extras/libmemif/adapter.go +++ b/extras/libmemif/adapter.go @@ -50,7 +50,7 @@ memif_cancel_poll_event () // are much easier to work with in cgo. typedef struct { - char *socket_filename; + memif_socket_handle_t socket; char *secret; uint8_t num_s2m_rings; uint8_t num_m2s_rings; @@ -108,7 +108,7 @@ govpp_memif_create (memif_conn_handle_t *conn, govpp_memif_conn_args_t *go_args, { memif_conn_args_t args; memset (&args, 0, sizeof (args)); - args.socket_filename = (char *)go_args->socket_filename; + args.socket = (char *)go_args->socket; if (go_args->secret != NULL) { strncpy ((char *)args.secret, go_args->secret, @@ -132,6 +132,12 @@ govpp_memif_create (memif_conn_handle_t *conn, govpp_memif_conn_args_t *go_args, private_ctx); } +static int +govpp_memif_create_socket (memif_socket_handle_t *sock, char *filename) +{ + return memif_create_socket(sock, filename, NULL); +} + // govpp_memif_get_details keeps reallocating buffer until it is large enough. // The buffer is returned to be deallocated when it is no longer needed. static int @@ -365,8 +371,9 @@ type Memif struct { MemifMeta // Per-library references - ifIndex int // index used in the Go-libmemif context (Context.memifs) - cHandle C.memif_conn_handle_t // handle used in C-libmemif + ifIndex int // index used in the Go-libmemif context (Context.memifs) + cHandle C.memif_conn_handle_t // connection handle used in C-libmemif + sHandle C.memif_socket_handle_t // socket handle used in C-libmemif // Callbacks callbacks *MemifCallbacks @@ -589,9 +596,13 @@ func CreateInterface(config *MemifConfig, callbacks *MemifCallbacks) (memif *Mem args := &C.govpp_memif_conn_args_t{} // - socket file name if config.SocketFilename != "" { - args.socket_filename = C.CString(config.SocketFilename) - defer C.free(unsafe.Pointer(args.socket_filename)) + log.WithField("name", config.SocketFilename).Debug("A new memif socket was created") + errCode := C.govpp_memif_create_socket(&memif.sHandle, C.CString(config.SocketFilename)) + if getMemifError(int(errCode)) != nil { + return nil, err + } } + args.socket = memif.sHandle // - interface ID args.interface_id = C.uint32_t(config.ConnID) // - interface name @@ -632,8 +643,7 @@ func CreateInterface(config *MemifConfig, callbacks *MemifCallbacks) (memif *Mem // Create memif in C-libmemif. errCode := C.govpp_memif_create(&memif.cHandle, args, unsafe.Pointer(uintptr(memif.ifIndex))) - err = getMemifError(int(errCode)) - if err != nil { + if getMemifError(int(errCode)) != nil { return nil, err } @@ -771,7 +781,7 @@ func (memif *Memif) TxBurst(queueID uint8, packets []RawPacketData) (count uint1 } var bufCount int - var buffers []*txPacketBuffer + buffers := make([]*txPacketBuffer, 0) cQueueID := C.uint16_t(queueID) for _, packet := range packets { @@ -916,6 +926,7 @@ func (memif *Memif) TxBurst(queueID uint8, packets []RawPacketData) (count uint1 // Rx queue. func (memif *Memif) RxBurst(queueID uint8, count uint16) (packets []RawPacketData, err error) { var recvCount C.uint16_t + packets = make([]RawPacketData, 0) if count == 0 { return packets, nil diff --git a/extras/libmemif/examples/gopacket/gopacket.go b/extras/libmemif/examples/gopacket/gopacket.go index ee452a2..2e3e04d 100644 --- a/extras/libmemif/examples/gopacket/gopacket.go +++ b/extras/libmemif/examples/gopacket/gopacket.go @@ -43,13 +43,13 @@ package main import ( "errors" "fmt" + "git.fd.io/govpp.git/extras/libmemif" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" "io" "net" "os" "os/signal" - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "git.fd.io/govpp.git/extras/libmemif" ) var ( diff --git a/extras/libmemif/examples/icmp-responder/icmp-responder.go b/extras/libmemif/examples/icmp-responder/icmp-responder.go index 5e9f2e0..79bb9d0 100644 --- a/extras/libmemif/examples/icmp-responder/icmp-responder.go +++ b/extras/libmemif/examples/icmp-responder/icmp-responder.go @@ -155,7 +155,7 @@ func IcmpResponder(memif *libmemif.Memif, queueID uint8) { break } // Generate response for each supported request. - responses := []libmemif.RawPacketData{} + var responses []libmemif.RawPacketData for _, packet := range packets { fmt.Println("Received new packet:") DumpPacket(packet) @@ -325,7 +325,7 @@ func main() { hwAddr, err = net.ParseMAC(MAC) if err != nil { - fmt.Println("Failed to parse the MAC address: %v", err) + fmt.Printf("Failed to parse the MAC address: %v", err) return } @@ -334,7 +334,7 @@ func main() { ipAddr = ip.To4() } if ipAddr == nil { - fmt.Println("Failed to parse the IP address: %v", err) + fmt.Printf("Failed to parse the IP address: %v", err) return } diff --git a/extras/libmemif/packethandle.go b/extras/libmemif/packethandle.go index 83bf90a..6889c94 100644 --- a/extras/libmemif/packethandle.go +++ b/extras/libmemif/packethandle.go @@ -16,9 +16,9 @@ package libmemif import ( "github.com/google/gopacket" - "time" - "sync" "io" + "sync" + "time" ) type memoizedPacket struct { @@ -55,7 +55,7 @@ func (memif *Memif) NewPacketHandle(queueId uint8, rxCount uint16) *MemifPacketH } } -// Reads packet data from memif in bursts, based on previously configured rxCount parameterer. Then caches the +// Reads packet data from memif in bursts, based on previously configured rxCount parameter. Then caches the // resulting packets and returns them 1 by 1 from this method until queue is empty then tries to call new rx burst // to read more data. If no data is returned, io.EOF error is thrown and caller should stop reading. func (handle *MemifPacketHandle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { -- cgit 1.2.3-korg