aboutsummaryrefslogtreecommitdiffstats
path: root/extras/libmemif/adapter.go
diff options
context:
space:
mode:
Diffstat (limited to 'extras/libmemif/adapter.go')
-rw-r--r--extras/libmemif/adapter.go44
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
}