diff options
Diffstat (limited to 'extras/libmemif/adapter.go')
-rw-r--r-- | extras/libmemif/adapter.go | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/extras/libmemif/adapter.go b/extras/libmemif/adapter.go index 1bb9229..ac8a827 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,14 +371,16 @@ 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 // Interrupt intCh chan uint8 // memif-global interrupt channel (value = queue ID) + intErrCh chan error // triggered when interrupt error occurs queueIntCh []chan struct{} // per RX queue interrupt channel // Rx/Tx queues @@ -578,6 +586,7 @@ func CreateInterface(config *MemifConfig, callbacks *MemifCallbacks) (memif *Mem // Initialize memif-global interrupt channel. memif.intCh = make(chan uint8, 1<<6) + memif.intErrCh = make(chan error, 1<<6) // Initialize event file descriptor for stopping Rx/Tx queue polling. memif.stopQPollFd = int(C.eventfd(0, C.EFD_NONBLOCK)) @@ -589,9 +598,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 +645,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 } @@ -657,6 +669,12 @@ func (memif *Memif) GetInterruptChan() (ch <-chan uint8 /* queue ID */) { return memif.intCh } +// GetInterruptErrorChan returns an Error channel +// which fires if there are errors occurred while read data. +func (memif *Memif) GetInterruptErrorChan() (ch <-chan error /* The error */) { + return memif.intErrCh +} + // GetQueueInterruptChan returns an empty-data channel which fires every time // there are data to read on a given queue. // It is only valid to call this function if memif is in the connected state. @@ -771,7 +789,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 +934,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 @@ -1011,6 +1030,7 @@ func (memif *Memif) Close() error { if err != nil { // Close memif-global interrupt channel. close(memif.intCh) + close(memif.intErrCh) // Close file descriptor stopQPollFd. C.close(C.int(memif.stopQPollFd)) } @@ -1146,7 +1166,13 @@ func pollRxQueue(memif *Memif, queueID uint8) { for { _, err := syscall.EpollWait(epFd, event[:], -1) if err != nil { + errno, _ := err.(syscall.Errno) + //EINTR and EAGAIN should not be considered as a fatal error, try again + if errno == syscall.EINTR || errno == syscall.EAGAIN { + continue + } log.WithField("err", err).Error("epoll_wait() failed") + memif.intErrCh <- err return } |