libmemif: version 2
[vpp.git] / extras / libmemif / src / main.c
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2017 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17
18 #include <stdint.h>
19 #include <net/if.h>
20 #include <sys/types.h>
21 #include <fcntl.h>
22 #include <sys/ioctl.h>
23 #include <sys/socket.h>
24 #include <sys/un.h>
25 #include <sys/uio.h>
26 #include <sys/mman.h>
27 #include <sys/prctl.h>
28 #include <inttypes.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <netdb.h>
32 #include <linux/ip.h>
33 #include <linux/icmp.h>
34 #include <arpa/inet.h>
35 #include <stdlib.h>
36 #include <netinet/if_ether.h>
37 #include <net/if_arp.h>
38 #include <asm/byteorder.h>
39 #include <byteswap.h>
40 #include <string.h>
41 #include <errno.h>
42 #include <sys/stat.h>
43 #include <sys/eventfd.h>
44 #include <sys/timerfd.h>
45 #include <sys/epoll.h>
46 #include <signal.h>
47
48 /* memif protocol msg, ring and descriptor definitions */
49 #include <memif.h>
50 /* memif api */
51 #include <libmemif.h>
52 /* socket messaging functions */
53 #include <socket.h>
54 /* private structs and functions */
55 #include <memif_private.h>
56
57 #define ERRLIST_LEN 38
58 #define MAX_ERRBUF_LEN 256
59
60 #if __x86_x64__
61 #define MEMIF_MEMORY_BARRIER() __builtin_ia32_sfence ()
62 #else
63 #define MEMIF_MEMORY_BARRIER() __sync_synchronize ()
64 #endif /* __x86_x64__ */
65
66 libmemif_main_t libmemif_main;
67 int memif_epfd;
68 int poll_cancel_fd = -1;
69
70 static char memif_buf[MAX_ERRBUF_LEN];
71
72 const char *memif_errlist[ERRLIST_LEN] = {      /* MEMIF_ERR_SUCCESS */
73   "Success.",
74   /* MEMIF_ERR_SYSCALL */
75   "Unspecified syscall error (build with -DMEMIF_DBG or make debug).",
76   /* MEMIF_ERR_ACCES */
77   "Permission to resoure denied.",
78   /* MEMIF_ERR_NO_FILE */
79   "Socket file does not exist",
80   /* MEMIF_ERR_FILE_LIMIT */
81   "System limit on total numer of open files reached.",
82   /* MEMIF_ERR_PROC_FILE_LIMIT */
83   "Per-process limit on total number of open files reached.",
84   /* MEMIF_ERR_ALREADY */
85   "Connection already requested.",
86   /* MEMIF_ERR_AGAIN */
87   "File descriptor refers to file other than socket, or operation would block.",
88   /* MEMIF_ERR_BAD_FD */
89   "Bad file descriptor.",
90   /* MEMIF_ERR_NOMEM */
91   "Out of memory.",
92   /* MEMIF_ERR_INVAL_ARG */
93   "Invalid argument.",
94   /* MEMIF_ERR_NOCONN */
95   "Memif connection handle does not point to existing conenction",
96   /* MEMIF_ERR_CONN */
97   "Memif connection handle points to existing connection",
98   /* MEMIF_ERR_CB_FDUPDATE */
99   "Callback memif_control_fd_update_t returned error",
100   /* MEMIF_ERR_FILE_NOT_SOCK */
101   "File specified by socket filename exists and is not socket.",
102   /* MEMIF_ERR_NO_SHMFD */
103   "Missing shared memory file descriptor. (internal error)",
104   /* MEMIF_ERR_COOKIE */
105   "Invalid cookie on ring. (internal error)",
106   /* MEMIF_ERR_NOBUF_RING */
107   "Ring buffer full.",
108   /* MEMIF_ERR_NOBUF */
109   "Not enough memif buffers. There are unreceived data in shared memory.",
110   /* MEMIF_ERR_NOBUF_DET */
111   "Not enough space for memif details in suplied buffer. String data might be malformed.",
112   /* MEMIF_ERR_INT_WRITE */
113   "Send interrupt error.",
114   /* MEMIF_ERR_MFMSG */
115   "Malformed message received on control channel.",
116   /* MEMIF_ERR_QID */
117   "Invalid queue id",
118   /* MEMIF_ERR_PROTO */
119   "Incompatible memory interface protocol version.",
120   /* MEMIF_ERR_ID */
121   "Unmatched interface id.",
122   /* MEMIF_ERR_ACCSLAVE */
123   "Slave cannot accept connection reqest.",
124   /* MEMIF_ERR_ALRCONN */
125   "Interface is already connected.",
126   /* MEMIF_ERR_MODE */
127   "Mode mismatch.",
128   /* MEMIF_ERR_SECRET */
129   "Secret mismatch.",
130   /* MEMIF_ERR_NOSECRET */
131   "Secret required.",
132   /* MEMIF_ERR_MAXREG */
133   "Limit on total number of regions reached.",
134   /* MEMIF_ERR_MAXRING */
135   "Limit on total number of ring reached.",
136   /* MEMIF_ERR_NO_INTFD */
137   "Missing interrupt file descriptor. (internal error)",
138   /* MEMIF_ERR_DISCONNECT */
139   "Interface received disconnect request.",
140   /* MEMIF_ERR_DISCONNECTED */
141   "Interface is disconnected.",
142   /* MEMIF_ERR_UNKNOWN_MSG */
143   "Unknown message type received on control channel. (internal error)",
144   /* MEMIF_ERR_POLL_CANCEL */
145   "Memif event polling was canceled.",
146   /* MEMIF_ERR_MAX_RING */
147   "Maximum log2 ring size is 15"
148 };
149
150 #define MEMIF_ERR_UNDEFINED "undefined error"
151
152 char *
153 memif_strerror (int err_code)
154 {
155   if (err_code >= ERRLIST_LEN)
156     {
157       strncpy (memif_buf, MEMIF_ERR_UNDEFINED, strlen (MEMIF_ERR_UNDEFINED));
158       memif_buf[strlen (MEMIF_ERR_UNDEFINED)] = '\0';
159     }
160   else
161     {
162       strncpy (memif_buf, memif_errlist[err_code],
163                strlen (memif_errlist[err_code]));
164       memif_buf[strlen (memif_errlist[err_code])] = '\0';
165     }
166   return memif_buf;
167 }
168
169 uint16_t
170 memif_get_version ()
171 {
172   return MEMIF_VERSION;
173 }
174
175 #define DBG_TX_BUF (0)
176 #define DBG_RX_BUF (1)
177
178 #ifdef MEMIF_DBG_SHM
179 static void
180 print_bytes (void *data, uint16_t len, uint8_t q)
181 {
182   if (q == DBG_TX_BUF)
183     printf ("\nTX:\n\t");
184   else
185     printf ("\nRX:\n\t");
186   int i;
187   for (i = 0; i < len; i++)
188     {
189       if (i % 8 == 0)
190         printf ("\n%d:\t", i);
191       printf ("%02X ", ((uint8_t *) (data))[i]);
192     }
193   printf ("\n\n");
194 }
195 #endif /* MEMIF_DBG_SHM */
196
197 int
198 memif_syscall_error_handler (int err_code)
199 {
200   DBG ("%s", strerror (err_code));
201
202   if (err_code == 0)
203     return MEMIF_ERR_SUCCESS;
204   if (err_code == EACCES)
205     return MEMIF_ERR_ACCES;
206   if (err_code == ENFILE)
207     return MEMIF_ERR_FILE_LIMIT;
208   if (err_code == EMFILE)
209     return MEMIF_ERR_PROC_FILE_LIMIT;
210   if (err_code == ENOMEM)
211     return MEMIF_ERR_NOMEM;
212 /* connection refused if master does not exist
213     this error would spam the user until master was created */
214   if (err_code == ECONNREFUSED)
215     return MEMIF_ERR_SUCCESS;
216   if (err_code == EALREADY)
217     return MEMIF_ERR_ALREADY;
218   if (err_code == EAGAIN)
219     return MEMIF_ERR_AGAIN;
220   if (err_code == EBADF)
221     return MEMIF_ERR_BAD_FD;
222   if (err_code == ENOENT)
223     return MEMIF_ERR_NO_FILE;
224
225   /* other syscall errors */
226   return MEMIF_ERR_SYSCALL;
227 }
228
229 static int
230 memif_add_epoll_fd (int fd, uint32_t events)
231 {
232   if (fd < 0)
233     {
234       DBG ("invalid fd %d", fd);
235       return -1;
236     }
237   struct epoll_event evt;
238   memset (&evt, 0, sizeof (evt));
239   evt.events = events;
240   evt.data.fd = fd;
241   if (epoll_ctl (memif_epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
242     {
243       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
244       return -1;
245     }
246   DBG ("fd %d added to epoll", fd);
247   return 0;
248 }
249
250 static int
251 memif_mod_epoll_fd (int fd, uint32_t events)
252 {
253   if (fd < 0)
254     {
255       DBG ("invalid fd %d", fd);
256       return -1;
257     }
258   struct epoll_event evt;
259   memset (&evt, 0, sizeof (evt));
260   evt.events = events;
261   evt.data.fd = fd;
262   if (epoll_ctl (memif_epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
263     {
264       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
265       return -1;
266     }
267   DBG ("fd %d moddified on epoll", fd);
268   return 0;
269 }
270
271 static int
272 memif_del_epoll_fd (int fd)
273 {
274   if (fd < 0)
275     {
276       DBG ("invalid fd %d", fd);
277       return -1;
278     }
279   struct epoll_event evt;
280   memset (&evt, 0, sizeof (evt));
281   if (epoll_ctl (memif_epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
282     {
283       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
284       return -1;
285     }
286   DBG ("fd %d removed from epoll", fd);
287   return 0;
288 }
289
290 int
291 memif_control_fd_update (int fd, uint8_t events)
292 {
293   if (events & MEMIF_FD_EVENT_DEL)
294     return memif_del_epoll_fd (fd);
295
296   uint32_t evt = 0;
297   if (events & MEMIF_FD_EVENT_READ)
298     evt |= EPOLLIN;
299   if (events & MEMIF_FD_EVENT_WRITE)
300     evt |= EPOLLOUT;
301
302   if (events & MEMIF_FD_EVENT_MOD)
303     return memif_mod_epoll_fd (fd, evt);
304
305   return memif_add_epoll_fd (fd, evt);
306 }
307
308 int
309 add_list_elt (memif_list_elt_t * e, memif_list_elt_t ** list, uint16_t * len)
310 {
311   libmemif_main_t *lm = &libmemif_main;
312
313   int i;
314   for (i = 0; i < *len; i++)
315     {
316       if ((*list)[i].data_struct == NULL)
317         {
318           (*list)[i].key = e->key;
319           (*list)[i].data_struct = e->data_struct;
320           return i;
321         }
322     }
323   memif_list_elt_t *tmp;
324   tmp = realloc (*list, sizeof (memif_list_elt_t) * *len * 2);
325   if (tmp == NULL)
326     return -1;
327
328   for (i = *len; i < *len * 2; i++)
329     {
330       tmp[i].key = -1;
331       tmp[i].data_struct = NULL;
332     }
333
334   tmp[*len].key = e->key;
335   tmp[*len].data_struct = e->data_struct;
336   i = *len;
337   *len = *len * 2;
338   *list = tmp;
339
340   return i;
341 }
342
343 int
344 get_list_elt (memif_list_elt_t ** e, memif_list_elt_t * list, uint16_t len,
345               int key)
346 {
347   if (key == -1)
348     {
349       *e = NULL;
350       return -1;
351     }
352   int i;
353   for (i = 0; i < len; i++)
354     {
355       if (list[i].key == key)
356         {
357           *e = &list[i];
358           return 0;
359         }
360     }
361   *e = NULL;
362   return -1;
363 }
364
365 /* does not free memory, only marks element as free */
366 int
367 free_list_elt (memif_list_elt_t * list, uint16_t len, int key)
368 {
369   int i;
370   for (i = 0; i < len; i++)
371     {
372       if (list[i].key == key)
373         {
374           list[i].key = -1;
375           list[i].data_struct = NULL;
376           return 0;
377         }
378     }
379
380   return -1;
381 }
382
383 int
384 free_list_elt_ctx (memif_list_elt_t * list, uint16_t len,
385                    memif_connection_t * ctx)
386 {
387   int i;
388   for (i = 0; i < len; i++)
389     {
390       if (list[i].key == -1)
391         {
392           if (list[i].data_struct == ctx)
393             {
394               list[i].data_struct = NULL;
395               return 0;
396             }
397         }
398     }
399
400   return -1;
401 }
402
403 static void
404 memif_control_fd_update_register (memif_control_fd_update_t * cb)
405 {
406   libmemif_main_t *lm = &libmemif_main;
407   lm->control_fd_update = cb;
408 }
409
410 static void
411 memif_alloc_register (memif_alloc_t * ma)
412 {
413   libmemif_main_t *lm = &libmemif_main;
414   lm->alloc = ma;
415 }
416
417 static void
418 memif_free_register (memif_free_t * mf)
419 {
420   libmemif_main_t *lm = &libmemif_main;
421   lm->free = mf;
422 }
423
424 int
425 memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
426             memif_alloc_t * memif_alloc, memif_free_t * memif_free)
427 {
428   int err = MEMIF_ERR_SUCCESS;  /* 0 */
429   libmemif_main_t *lm = &libmemif_main;
430   memset (lm, 0, sizeof (libmemif_main_t));
431
432   if (memif_alloc != NULL)
433     {
434       memif_alloc_register (memif_alloc);
435     }
436   else
437     memif_alloc_register (malloc);
438
439   if (memif_free != NULL)
440     memif_free_register (memif_free);
441   else
442     memif_free_register (free);
443
444   if (app_name != NULL)
445     {
446       uint8_t len = (strlen (app_name) > MEMIF_NAME_LEN)
447         ? strlen (app_name) : MEMIF_NAME_LEN;
448       strncpy ((char *) lm->app_name, app_name, len);
449     }
450   else
451     {
452       strncpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
453                strlen (MEMIF_DEFAULT_APP_NAME));
454     }
455
456   /* register control fd update callback */
457   if (on_control_fd_update != NULL)
458     memif_control_fd_update_register (on_control_fd_update);
459   else
460     {
461       memif_epfd = epoll_create (1);
462       memif_control_fd_update_register (memif_control_fd_update);
463       if ((poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
464         {
465           err = errno;
466           DBG ("eventfd: %s", strerror (err));
467           return memif_syscall_error_handler (err);
468         }
469       lm->control_fd_update (poll_cancel_fd, MEMIF_FD_EVENT_READ);
470       DBG ("libmemif event polling initialized");
471     }
472
473   lm->control_list_len = 2;
474   lm->interrupt_list_len = 2;
475   lm->listener_list_len = 1;
476   lm->pending_list_len = 1;
477
478   lm->control_list =
479     lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
480   if (lm->control_list == NULL)
481     {
482       err = MEMIF_ERR_NOMEM;
483       goto error;
484     }
485   lm->interrupt_list =
486     lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
487   if (lm->interrupt_list == NULL)
488     {
489       err = MEMIF_ERR_NOMEM;
490       goto error;
491     }
492   lm->listener_list =
493     lm->alloc (sizeof (memif_list_elt_t) * lm->listener_list_len);
494   if (lm->listener_list == NULL)
495     {
496       err = MEMIF_ERR_NOMEM;
497       goto error;
498     }
499   lm->pending_list =
500     lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
501   if (lm->pending_list == NULL)
502     {
503       err = MEMIF_ERR_NOMEM;
504       goto error;
505     }
506
507   int i;
508   for (i = 0; i < lm->control_list_len; i++)
509     {
510       lm->control_list[i].key = -1;
511       lm->control_list[i].data_struct = NULL;
512     }
513   for (i = 0; i < lm->interrupt_list_len; i++)
514     {
515       lm->interrupt_list[i].key = -1;
516       lm->interrupt_list[i].data_struct = NULL;
517     }
518   for (i = 0; i < lm->listener_list_len; i++)
519     {
520       lm->listener_list[i].key = -1;
521       lm->listener_list[i].data_struct = NULL;
522     }
523   for (i = 0; i < lm->pending_list_len; i++)
524     {
525       lm->pending_list[i].key = -1;
526       lm->pending_list[i].data_struct = NULL;
527     }
528
529   lm->disconn_slaves = 0;
530
531   lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
532   if (lm->timerfd < 0)
533     {
534       err = memif_syscall_error_handler (errno);
535       goto error;
536     }
537
538   lm->arm.it_value.tv_sec = 2;
539   lm->arm.it_value.tv_nsec = 0;
540   lm->arm.it_interval.tv_sec = 2;
541   lm->arm.it_interval.tv_nsec = 0;
542
543   if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ) < 0)
544     {
545       DBG ("callback type memif_control_fd_update_t error!");
546       err = MEMIF_ERR_CB_FDUPDATE;
547       goto error;
548     }
549
550   return err;
551
552 error:
553   memif_cleanup ();
554   return err;
555 }
556
557 static inline memif_ring_t *
558 memif_get_ring (memif_connection_t * conn, memif_ring_type_t type,
559                 uint16_t ring_num)
560 {
561   if (&conn->regions[0] == NULL)
562     return NULL;
563   void *p = conn->regions[0].shm;
564   int ring_size =
565     sizeof (memif_ring_t) +
566     sizeof (memif_desc_t) * (1 << conn->run_args.log2_ring_size);
567   p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
568
569   return (memif_ring_t *) p;
570 }
571
572 int
573 memif_set_rx_mode (memif_conn_handle_t c, memif_rx_mode_t rx_mode,
574                    uint16_t qid)
575 {
576   memif_connection_t *conn = (memif_connection_t *) c;
577   if (conn == NULL)
578     return MEMIF_ERR_NOCONN;
579   uint8_t num =
580     (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->run_args.
581     num_m2s_rings;
582   if (qid >= num)
583     return MEMIF_ERR_QID;
584
585   conn->rx_queues[qid].ring->flags = rx_mode;
586   DBG ("rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
587   return MEMIF_ERR_SUCCESS;
588 }
589
590 int
591 memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
592               memif_connection_update_t * on_connect,
593               memif_connection_update_t * on_disconnect,
594               memif_interrupt_t * on_interrupt, void *private_ctx)
595 {
596   libmemif_main_t *lm = &libmemif_main;
597   int err, i, index, sockfd = -1;
598   memif_list_elt_t list_elt;
599   memif_connection_t *conn = (memif_connection_t *) * c;
600   if (conn != NULL)
601     {
602       DBG ("This handle already points to existing memif.");
603       return MEMIF_ERR_CONN;
604     }
605   conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
606   if (conn == NULL)
607     {
608       err = MEMIF_ERR_NOMEM;
609       goto error;
610     }
611   memset (conn, 0, sizeof (memif_connection_t));
612
613   conn->args.interface_id = args->interface_id;
614
615   if (args->log2_ring_size == 0)
616     args->log2_ring_size = MEMIF_DEFAULT_LOG2_RING_SIZE;
617   else if (args->log2_ring_size > MEMIF_MAX_LOG2_RING_SIZE)
618     {
619       err = MEMIF_ERR_MAX_RING;
620       goto error;
621     }
622   if (args->buffer_size == 0)
623     args->buffer_size = MEMIF_DEFAULT_BUFFER_SIZE;
624   if (args->num_s2m_rings == 0)
625     args->num_s2m_rings = MEMIF_DEFAULT_TX_QUEUES;
626   if (args->num_m2s_rings == 0)
627     args->num_m2s_rings = MEMIF_DEFAULT_RX_QUEUES;
628
629   conn->args.num_s2m_rings = args->num_s2m_rings;
630   conn->args.num_m2s_rings = args->num_m2s_rings;
631   conn->args.buffer_size = args->buffer_size;
632   conn->args.log2_ring_size = args->log2_ring_size;
633   conn->args.is_master = args->is_master;
634   conn->args.mode = args->mode;
635   conn->msg_queue = NULL;
636   conn->regions = NULL;
637   conn->tx_queues = NULL;
638   conn->rx_queues = NULL;
639   conn->fd = -1;
640   conn->on_connect = on_connect;
641   conn->on_disconnect = on_disconnect;
642   conn->on_interrupt = on_interrupt;
643   conn->private_ctx = private_ctx;
644   memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
645
646   uint8_t l = strlen ((char *) args->interface_name);
647   strncpy ((char *) conn->args.interface_name, (char *) args->interface_name,
648            l);
649
650   /* allocate and initialize socket_filename so it can be copyed to sun_path
651      without memory leaks */
652   conn->args.socket_filename = lm->alloc (sizeof (char *) * 108);
653   if (conn->args.socket_filename == NULL)
654     {
655       err = MEMIF_ERR_NOMEM;
656       goto error;
657     }
658   memset (conn->args.socket_filename, 0, 108 * sizeof (char *));
659
660   if (args->socket_filename)
661     {
662       if (conn->args.socket_filename == NULL)
663         {
664           err = memif_syscall_error_handler (errno);
665           goto error;
666         }
667       strncpy ((char *) conn->args.socket_filename,
668                (char *) args->socket_filename,
669                strlen ((char *) args->socket_filename));
670     }
671   else
672     {
673       uint16_t sdl = strlen (MEMIF_DEFAULT_SOCKET_DIR);
674       uint16_t sfl = strlen (MEMIF_DEFAULT_SOCKET_FILENAME);
675       if (conn->args.socket_filename == NULL)
676         {
677           err = memif_syscall_error_handler (errno);
678           goto error;
679         }
680       strncpy ((char *) conn->args.socket_filename,
681                MEMIF_DEFAULT_SOCKET_DIR, sdl);
682       conn->args.socket_filename[sdl] = '/';
683       strncpy ((char *) (conn->args.socket_filename + 1 + sdl),
684                MEMIF_DEFAULT_SOCKET_FILENAME, sfl);
685     }
686
687   if (args->secret)
688     {
689       l = strlen ((char *) args->secret);
690       strncpy ((char *) conn->args.secret, (char *) args->secret, l);
691     }
692
693   if (conn->args.is_master)
694     {
695       conn->run_args.buffer_size = conn->args.buffer_size;
696       memif_socket_t *ms;
697       memif_list_elt_t elt;
698       for (i = 0; i < lm->listener_list_len; i++)
699         {
700           if ((ms =
701                (memif_socket_t *) lm->listener_list[i].data_struct) != NULL)
702             {
703               if (strncmp
704                   ((char *) ms->filename, (char *) conn->args.socket_filename,
705                    strlen ((char *) ms->filename)) == 0)
706                 {
707                   /* add interface to listener socket */
708                   elt.key = conn->args.interface_id;
709                   *c = elt.data_struct = conn;
710                   add_list_elt (&elt, &ms->interface_list,
711                                 &ms->interface_list_len);
712                   ms->use_count++;
713                   conn->listener_fd = ms->fd;
714                   break;
715                 }
716             }
717           else
718             {
719               struct stat file_stat;
720               if (stat ((char *) conn->args.socket_filename, &file_stat) == 0)
721                 {
722                   if (S_ISSOCK (file_stat.st_mode))
723                     unlink ((char *) conn->args.socket_filename);
724                   else
725                     return memif_syscall_error_handler (errno);
726                 }
727               DBG ("creating socket file");
728               ms = lm->alloc (sizeof (memif_socket_t));
729               if (ms == NULL)
730                 {
731                   err = MEMIF_ERR_NOMEM;
732                   goto error;
733                 }
734               ms->filename =
735                 lm->alloc (strlen ((char *) conn->args.socket_filename) +
736                            sizeof (char));
737               if (ms->filename == NULL)
738                 {
739                   err = MEMIF_ERR_NOMEM;
740                   goto error;
741                 }
742               memset (ms->filename, 0,
743                       strlen ((char *) conn->args.socket_filename) +
744                       sizeof (char));
745               strncpy ((char *) ms->filename,
746                        (char *) conn->args.socket_filename,
747                        strlen ((char *) conn->args.socket_filename));
748               ms->interface_list_len = 1;
749               ms->interface_list =
750                 lm->alloc (sizeof (memif_list_elt_t) *
751                            ms->interface_list_len);
752               if (ms->interface_list == NULL)
753                 {
754                   err = MEMIF_ERR_NOMEM;
755                   goto error;
756                 }
757               ms->interface_list[0].key = -1;
758               ms->interface_list[0].data_struct = NULL;
759               struct sockaddr_un un = { 0 };
760               int on = 1;
761
762               ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
763               if (ms->fd < 0)
764                 {
765                   err = memif_syscall_error_handler (errno);
766                   goto error;
767                 }
768               DBG ("socket %d created", ms->fd);
769               un.sun_family = AF_UNIX;
770               strncpy ((char *) un.sun_path, (char *) ms->filename,
771                        sizeof (un.sun_path) - 1);
772               DBG ("sockopt");
773               if (setsockopt
774                   (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
775                 {
776                   err = memif_syscall_error_handler (errno);
777                   goto error;
778                 }
779               DBG ("bind");
780               if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
781                 {
782                   err = memif_syscall_error_handler (errno);
783                   goto error;
784                 }
785               DBG ("listen");
786               if (listen (ms->fd, 1) < 0)
787                 {
788                   err = memif_syscall_error_handler (errno);
789                   goto error;
790                 }
791               DBG ("stat");
792               if (stat ((char *) ms->filename, &file_stat) < 0)
793                 {
794                   err = memif_syscall_error_handler (errno);
795                   goto error;
796                 }
797
798               /* add interface to listener socket */
799               elt.key = conn->args.interface_id;
800               *c = elt.data_struct = conn;
801               add_list_elt (&elt, &ms->interface_list,
802                             &ms->interface_list_len);
803               ms->use_count = 1;
804               conn->listener_fd = ms->fd;
805
806               /* add listener socket to libmemif main */
807               elt.key = ms->fd;
808               elt.data_struct = ms;
809               add_list_elt (&elt, &lm->listener_list, &lm->listener_list_len);
810               lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_READ);
811               break;
812             }
813         }
814     }
815   else
816     {
817       if (lm->disconn_slaves == 0)
818         {
819           if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
820             {
821               err = memif_syscall_error_handler (errno);
822               goto error;
823             }
824         }
825
826       lm->disconn_slaves++;
827
828       list_elt.key = -1;
829       *c = list_elt.data_struct = conn;
830       if ((index =
831            add_list_elt (&list_elt, &lm->control_list,
832                          &lm->control_list_len)) < 0)
833         {
834           err = MEMIF_ERR_NOMEM;
835           goto error;
836         }
837     }
838
839   conn->index = index;
840
841   return 0;
842
843 error:
844   if (sockfd > 0)
845     close (sockfd);
846   sockfd = -1;
847   if (conn->args.socket_filename)
848     lm->free (conn->args.socket_filename);
849   if (conn != NULL)
850     lm->free (conn);
851   *c = conn = NULL;
852   return err;
853 }
854
855 int
856 memif_control_fd_handler (int fd, uint8_t events)
857 {
858   int i, rv, sockfd = -1, err = MEMIF_ERR_SUCCESS;      /* 0 */
859   uint16_t num;
860   memif_list_elt_t *e = NULL;
861   memif_connection_t *conn;
862   libmemif_main_t *lm = &libmemif_main;
863   if (fd == lm->timerfd)
864     {
865       uint64_t b;
866       ssize_t size;
867       size = read (fd, &b, sizeof (b));
868       for (i = 0; i < lm->control_list_len; i++)
869         {
870           if ((lm->control_list[i].key < 0)
871               && (lm->control_list[i].data_struct != NULL))
872             {
873               conn = lm->control_list[i].data_struct;
874               if (conn->args.is_master)
875                 continue;
876
877               struct sockaddr_un sun;
878               sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
879               if (sockfd < 0)
880                 {
881                   err = memif_syscall_error_handler (errno);
882                   goto error;
883                 }
884
885               sun.sun_family = AF_UNIX;
886
887               strncpy (sun.sun_path, conn->args.socket_filename,
888                        sizeof (sun.sun_path) - 1);
889
890               if (connect (sockfd, (struct sockaddr *) &sun,
891                            sizeof (struct sockaddr_un)) == 0)
892                 {
893                   conn->fd = sockfd;
894                   conn->read_fn = memif_conn_fd_read_ready;
895                   conn->write_fn = memif_conn_fd_write_ready;
896                   conn->error_fn = memif_conn_fd_error;
897
898                   lm->control_list[conn->index].key = conn->fd;
899
900                   lm->control_fd_update (sockfd,
901                                          MEMIF_FD_EVENT_READ |
902                                          MEMIF_FD_EVENT_WRITE);
903
904                   lm->disconn_slaves--;
905                   if (lm->disconn_slaves == 0)
906                     {
907                       if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL)
908                           < 0)
909                         {
910                           err = memif_syscall_error_handler (errno);
911                           goto error;
912                         }
913                     }
914                 }
915               else
916                 {
917                   err = memif_syscall_error_handler (errno);
918                   goto error;
919                 }
920             }
921         }
922     }
923   else
924     {
925       get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
926       if (e != NULL)
927         {
928           if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
929             {
930               num =
931                 (((memif_connection_t *) e->data_struct)->args.
932                  is_master) ? ((memif_connection_t *) e->data_struct)->
933                 run_args.num_s2m_rings : ((memif_connection_t *) e->
934                                           data_struct)->run_args.
935                 num_m2s_rings;
936               for (i = 0; i < num; i++)
937                 {
938                   if (((memif_connection_t *) e->data_struct)->rx_queues[i].
939                       int_fd == fd)
940                     {
941                       ((memif_connection_t *) e->
942                        data_struct)->on_interrupt ((void *) e->data_struct,
943                                                    ((memif_connection_t *)
944                                                     e->data_struct)->
945                                                    private_ctx, i);
946                       return MEMIF_ERR_SUCCESS;
947                     }
948                 }
949             }
950           return MEMIF_ERR_SUCCESS;
951         }
952       get_list_elt (&e, lm->listener_list, lm->listener_list_len, fd);
953       if (e != NULL)
954         {
955           memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
956           return MEMIF_ERR_SUCCESS;
957         }
958
959       get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
960       if (e != NULL)
961         {
962           memif_read_ready (fd);
963           return MEMIF_ERR_SUCCESS;
964         }
965
966       get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
967       if (e != NULL)
968         {
969           if (events & MEMIF_FD_EVENT_READ)
970             {
971               err =
972                 ((memif_connection_t *) e->data_struct)->read_fn (e->
973                                                                   data_struct);
974               if (err != MEMIF_ERR_SUCCESS)
975                 return err;
976             }
977           if (events & MEMIF_FD_EVENT_WRITE)
978             {
979               err =
980                 ((memif_connection_t *) e->data_struct)->write_fn (e->
981                                                                    data_struct);
982               if (err != MEMIF_ERR_SUCCESS)
983                 return err;
984             }
985           if (events & MEMIF_FD_EVENT_ERROR)
986             {
987               err =
988                 ((memif_connection_t *) e->data_struct)->error_fn (e->
989                                                                    data_struct);
990               if (err != MEMIF_ERR_SUCCESS)
991                 return err;
992             }
993         }
994     }
995
996   return MEMIF_ERR_SUCCESS;     /* 0 */
997
998 error:
999   if (sockfd > 0)
1000     close (sockfd);
1001   sockfd = -1;
1002   return err;
1003 }
1004
1005 int
1006 memif_poll_event (int timeout)
1007 {
1008   libmemif_main_t *lm = &libmemif_main;
1009   memif_list_elt_t *elt;
1010   struct epoll_event evt, *e;
1011   int en = 0, err = MEMIF_ERR_SUCCESS, i = 0;   /* 0 */
1012   uint16_t num;
1013   uint32_t events = 0;
1014   uint64_t counter = 0;
1015   ssize_t r = 0;
1016   memset (&evt, 0, sizeof (evt));
1017   evt.events = EPOLLIN | EPOLLOUT;
1018   sigset_t sigset;
1019   sigemptyset (&sigset);
1020   en = epoll_pwait (memif_epfd, &evt, 1, timeout, &sigset);
1021   if (en < 0)
1022     {
1023       err = errno;
1024       DBG ("epoll_pwait: %s", strerror (err));
1025       return memif_syscall_error_handler (err);
1026     }
1027   if (en > 0)
1028     {
1029       if (evt.data.fd == poll_cancel_fd)
1030         {
1031           r = read (evt.data.fd, &counter, sizeof (counter));
1032           return MEMIF_ERR_POLL_CANCEL;
1033         }
1034       if (evt.events & EPOLLIN)
1035         events |= MEMIF_FD_EVENT_READ;
1036       if (evt.events & EPOLLOUT)
1037         events |= MEMIF_FD_EVENT_WRITE;
1038       if (evt.events & EPOLLERR)
1039         events |= MEMIF_FD_EVENT_ERROR;
1040       err = memif_control_fd_handler (evt.data.fd, events);
1041       return err;
1042     }
1043   return 0;
1044 }
1045
1046 int
1047 memif_cancel_poll_event ()
1048 {
1049   uint64_t counter = 1;
1050   ssize_t w = 0;
1051
1052   if (poll_cancel_fd == -1)
1053     return 0;
1054   w = write (poll_cancel_fd, &counter, sizeof (counter));
1055   if (w < sizeof (counter))
1056     return MEMIF_ERR_INT_WRITE;
1057
1058   return 0;
1059 }
1060
1061 static void
1062 memif_msg_queue_free (libmemif_main_t * lm, memif_msg_queue_elt_t ** e)
1063 {
1064   if (*e == NULL)
1065     return;
1066   memif_msg_queue_free (lm, &(*e)->next);
1067   lm->free (*e);
1068   *e = NULL;
1069   return;
1070 }
1071
1072 /* send disconnect msg and close interface */
1073 int
1074 memif_disconnect_internal (memif_connection_t * c)
1075 {
1076   if (c == NULL)
1077     {
1078       DBG ("no connection");
1079       return MEMIF_ERR_NOCONN;
1080     }
1081   uint16_t num;
1082   int err = MEMIF_ERR_SUCCESS, i;       /* 0 */
1083   memif_queue_t *mq;
1084   libmemif_main_t *lm = &libmemif_main;
1085   memif_list_elt_t *e;
1086
1087   c->on_disconnect ((void *) c, c->private_ctx);
1088
1089   if (c->fd > 0)
1090     {
1091       memif_msg_send_disconnect (c->fd, "interface deleted", 0);
1092       lm->control_fd_update (c->fd, MEMIF_FD_EVENT_DEL);
1093       close (c->fd);
1094     }
1095   get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
1096   if (e != NULL)
1097     {
1098       if (c->args.is_master)
1099         free_list_elt (lm->control_list, lm->control_list_len, c->fd);
1100       e->key = c->fd = -1;
1101     }
1102
1103   if (c->tx_queues != NULL)
1104     {
1105       num =
1106         (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1107         num_s2m_rings;
1108       for (i = 0; i < num; i++)
1109         {
1110           mq = &c->tx_queues[i];
1111           if (mq != NULL)
1112             {
1113               if (mq->int_fd > 0)
1114                 close (mq->int_fd);
1115               free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1116                              mq->int_fd);
1117               mq->int_fd = -1;
1118             }
1119         }
1120       lm->free (c->tx_queues);
1121       c->tx_queues = NULL;
1122     }
1123
1124   if (c->rx_queues != NULL)
1125     {
1126       num =
1127         (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1128         num_m2s_rings;
1129       for (i = 0; i < num; i++)
1130         {
1131           mq = &c->rx_queues[i];
1132           if (mq != NULL)
1133             {
1134               if (mq->int_fd > 0)
1135                 {
1136                   if (c->on_interrupt != NULL)
1137                     lm->control_fd_update (mq->int_fd, MEMIF_FD_EVENT_DEL);
1138                   close (mq->int_fd);
1139                 }
1140               free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1141                              mq->int_fd);
1142               mq->int_fd = -1;
1143             }
1144         }
1145       lm->free (c->rx_queues);
1146       c->rx_queues = NULL;
1147     }
1148
1149   if (c->regions != NULL)
1150     {
1151       if (munmap (c->regions[0].shm, c->regions[0].region_size) < 0)
1152         return memif_syscall_error_handler (errno);
1153       if (c->regions[0].fd > 0)
1154         close (c->regions[0].fd);
1155       c->regions[0].fd = -1;
1156       lm->free (c->regions);
1157       c->regions = NULL;
1158     }
1159
1160   memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
1161
1162   memif_msg_queue_free (lm, &c->msg_queue);
1163
1164   if (!(c->args.is_master))
1165     {
1166       if (lm->disconn_slaves == 0)
1167         {
1168           if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1169             {
1170               err = memif_syscall_error_handler (errno);
1171               DBG ("timerfd_settime: arm");
1172             }
1173         }
1174       lm->disconn_slaves++;
1175     }
1176
1177   return err;
1178 }
1179
1180 int
1181 memif_delete (memif_conn_handle_t * conn)
1182 {
1183   memif_connection_t *c = (memif_connection_t *) * conn;
1184   if (c == NULL)
1185     {
1186       DBG ("no connection");
1187       return MEMIF_ERR_NOCONN;
1188     }
1189   libmemif_main_t *lm = &libmemif_main;
1190   memif_list_elt_t *e = NULL;
1191   memif_socket_t *ms = NULL;
1192
1193   int err = MEMIF_ERR_SUCCESS;
1194
1195   if (c->fd > 0)
1196     {
1197       DBG ("DISCONNECTING");
1198       err = memif_disconnect_internal (c);
1199       if (err == MEMIF_ERR_NOCONN)
1200         return err;
1201     }
1202
1203   free_list_elt_ctx (lm->control_list, lm->control_list_len, c);
1204
1205   if (c->args.is_master)
1206     {
1207       get_list_elt (&e, lm->listener_list, lm->listener_list_len,
1208                     c->listener_fd);
1209       if (e != NULL)
1210         {
1211           ms = (memif_socket_t *) e->data_struct;
1212           ms->use_count--;
1213           free_list_elt (ms->interface_list, ms->interface_list_len,
1214                          c->args.interface_id);
1215           if (ms->use_count <= 0)
1216             {
1217               lm->control_fd_update (c->listener_fd, MEMIF_FD_EVENT_DEL);
1218               free_list_elt (lm->listener_list, lm->listener_list_len,
1219                              c->listener_fd);
1220               close (c->listener_fd);
1221               c->listener_fd = ms->fd = -1;
1222               lm->free (ms->interface_list);
1223               ms->interface_list = NULL;
1224               lm->free (ms->filename);
1225               ms->filename = NULL;
1226               lm->free (ms);
1227               ms = NULL;
1228             }
1229         }
1230     }
1231   else
1232     {
1233       lm->disconn_slaves--;
1234       if (lm->disconn_slaves <= 0)
1235         {
1236           if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1237             {
1238               err = memif_syscall_error_handler (errno);
1239               DBG ("timerfd_settime: disarm");
1240             }
1241         }
1242     }
1243
1244   if (c->args.socket_filename)
1245     lm->free (c->args.socket_filename);
1246   c->args.socket_filename = NULL;
1247
1248   lm->free (c);
1249   c = NULL;
1250
1251   *conn = c;
1252   return err;
1253 }
1254
1255 int
1256 memif_connect1 (memif_connection_t * c)
1257 {
1258   libmemif_main_t *lm = &libmemif_main;
1259   memif_region_t *mr = c->regions;
1260   memif_queue_t *mq;
1261   int i;
1262   uint16_t num;
1263
1264   if (mr != NULL)
1265     {
1266       if (!mr->shm)
1267         {
1268           if (mr->fd < 0)
1269             return MEMIF_ERR_NO_SHMFD;
1270
1271           if ((mr->shm = mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
1272                                MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
1273             {
1274               return memif_syscall_error_handler (errno);
1275             }
1276         }
1277     }
1278
1279   num =
1280     (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1281     num_s2m_rings;
1282   for (i = 0; i < num; i++)
1283     {
1284       mq = &c->tx_queues[i];
1285       if (mq != NULL)
1286         {
1287           mq->ring = c->regions[mq->region].shm + mq->offset;
1288           if (mq->ring->cookie != MEMIF_COOKIE)
1289             {
1290               DBG ("wrong cookie on tx ring %u", i);
1291               return MEMIF_ERR_COOKIE;
1292             }
1293           mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1294             0;
1295         }
1296     }
1297   num =
1298     (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1299     num_m2s_rings;
1300   for (i = 0; i < num; i++)
1301     {
1302       mq = &c->rx_queues[i];
1303       if (mq != NULL)
1304         {
1305           mq->ring = c->regions[mq->region].shm + mq->offset;
1306           if (mq->ring->cookie != MEMIF_COOKIE)
1307             {
1308               DBG ("wrong cookie on rx ring %u", i);
1309               return MEMIF_ERR_COOKIE;
1310             }
1311           mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1312             0;
1313         }
1314     }
1315
1316   lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD);
1317
1318   return 0;
1319 }
1320
1321 int
1322 memif_init_regions_and_queues (memif_connection_t * conn)
1323 {
1324   memif_ring_t *ring = NULL;
1325   uint64_t buffer_offset;
1326   memif_region_t *r;
1327   int i, j;
1328   libmemif_main_t *lm = &libmemif_main;
1329   memif_list_elt_t e;
1330
1331   conn->regions = (memif_region_t *) lm->alloc (sizeof (memif_region_t));
1332   if (conn->regions == NULL)
1333     return MEMIF_ERR_NOMEM;
1334   r = conn->regions;
1335
1336   buffer_offset =
1337     (conn->run_args.num_s2m_rings +
1338      conn->run_args.num_m2s_rings) * (sizeof (memif_ring_t) +
1339                                       sizeof (memif_desc_t) *
1340                                       (1 << conn->run_args.log2_ring_size));
1341
1342   r->region_size = buffer_offset +
1343     conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1344     (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1345
1346   if ((r->fd =
1347        memif_memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1348     return memif_syscall_error_handler (errno);
1349
1350   if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
1351     return memif_syscall_error_handler (errno);
1352
1353   if ((ftruncate (r->fd, r->region_size)) == -1)
1354     return memif_syscall_error_handler (errno);
1355
1356   if ((r->shm = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
1357                       MAP_SHARED, r->fd, 0)) == MAP_FAILED)
1358     return memif_syscall_error_handler (errno);
1359
1360   for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1361     {
1362       ring = memif_get_ring (conn, MEMIF_RING_S2M, i);
1363       DBG ("RING: %p I: %d", ring, i);
1364       ring->head = ring->tail = 0;
1365       ring->cookie = MEMIF_COOKIE;
1366       ring->flags = 0;
1367       for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1368         {
1369           uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1370           ring->desc[j].region = 0;
1371           ring->desc[j].offset = buffer_offset +
1372             (uint32_t) (slot * conn->run_args.buffer_size);
1373           ring->desc[j].length = conn->run_args.buffer_size;
1374         }
1375     }
1376   for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1377     {
1378       ring = memif_get_ring (conn, MEMIF_RING_M2S, i);
1379       DBG ("RING: %p I: %d", ring, i);
1380       ring->head = ring->tail = 0;
1381       ring->cookie = MEMIF_COOKIE;
1382       ring->flags = 0;
1383       for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1384         {
1385           uint16_t slot =
1386             (i +
1387              conn->run_args.num_s2m_rings) *
1388             (1 << conn->run_args.log2_ring_size) + j;
1389           ring->desc[j].region = 0;
1390           ring->desc[j].offset = buffer_offset +
1391             (uint32_t) (slot * conn->run_args.buffer_size);
1392           ring->desc[j].length = conn->run_args.buffer_size;
1393         }
1394     }
1395   memif_queue_t *mq;
1396   mq =
1397     (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
1398                                  conn->run_args.num_s2m_rings);
1399   if (mq == NULL)
1400     return MEMIF_ERR_NOMEM;
1401   int x;
1402   for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1403     {
1404       if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1405         return memif_syscall_error_handler (errno);
1406       /* add int fd to interrupt fd list */
1407       e.key = mq[x].int_fd;
1408       e.data_struct = conn;
1409       add_list_elt (&e, &lm->interrupt_list, &lm->interrupt_list_len);
1410
1411       mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
1412       DBG ("RING: %p I: %d", mq[x].ring, x);
1413       mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1414       mq[x].region = 0;
1415       mq[x].offset =
1416         (void *) mq[x].ring - (void *) conn->regions[mq->region].shm;
1417       mq[x].last_head = 0;
1418       mq[x].last_tail = 0;
1419       mq[x].alloc_bufs = 0;
1420     }
1421   conn->tx_queues = mq;
1422
1423   mq =
1424     (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
1425                                  conn->run_args.num_m2s_rings);
1426   if (mq == NULL)
1427     return MEMIF_ERR_NOMEM;
1428   for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1429     {
1430       if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1431         return memif_syscall_error_handler (errno);
1432       /* add int fd to interrupt fd list */
1433       e.key = mq[x].int_fd;
1434       e.data_struct = conn;
1435       add_list_elt (&e, &lm->interrupt_list, &lm->interrupt_list_len);
1436
1437       mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
1438       DBG ("RING: %p I: %d", mq[x].ring, x);
1439       mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1440       mq[x].region = 0;
1441       mq[x].offset =
1442         (void *) mq[x].ring - (void *) conn->regions[mq->region].shm;
1443       mq[x].last_head = 0;
1444       mq[x].last_tail = 0;
1445       mq[x].alloc_bufs = 0;
1446     }
1447   conn->rx_queues = mq;
1448
1449   return 0;
1450 }
1451
1452 int
1453 memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
1454                     memif_buffer_t * bufs, uint16_t count,
1455                     uint16_t * count_out, uint16_t size)
1456 {
1457   memif_connection_t *c = (memif_connection_t *) conn;
1458   if (EXPECT_FALSE (c == NULL))
1459     return MEMIF_ERR_NOCONN;
1460   if (EXPECT_FALSE (c->fd < 0))
1461     return MEMIF_ERR_DISCONNECTED;
1462   uint8_t num =
1463     (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1464     num_s2m_rings;
1465   if (EXPECT_FALSE (qid >= num))
1466     return MEMIF_ERR_QID;
1467   if (EXPECT_FALSE (!count_out))
1468     return MEMIF_ERR_INVAL_ARG;
1469
1470   memif_queue_t *mq = &c->tx_queues[qid];
1471   memif_ring_t *ring = mq->ring;
1472   memif_buffer_t *b0, *b1;
1473   uint16_t mask = (1 << mq->log2_ring_size) - 1;
1474   uint16_t ring_size;
1475   uint16_t slot, ns;
1476   int i, err = MEMIF_ERR_SUCCESS;       /* 0 */
1477   uint16_t dst_left, src_left;
1478   uint16_t saved_count;
1479   memif_buffer_t *saved_b;
1480   *count_out = 0;
1481
1482   ring_size = (1 << mq->log2_ring_size);
1483   ns = ring->tail - mq->last_tail;
1484   mq->last_tail += ns;
1485   slot = (c->args.is_master) ? ring->tail : ring->head;
1486   slot += mq->alloc_bufs;
1487
1488   if (c->args.is_master)
1489     ns = ring->head + mq->alloc_bufs - ring->tail;
1490   else
1491     ns = ring_size - ring->head + mq->alloc_bufs + mq->last_tail;
1492
1493   while (count && ns)
1494     {
1495       b0 = (bufs + *count_out);
1496
1497       saved_b = b0;
1498       saved_count = count;
1499
1500       b0->desc_index = slot;
1501       ring->desc[slot & mask].flags = 0;
1502
1503       /* slave can produce buffer with original length */
1504       dst_left = (c->args.is_master) ? ring->desc[slot & mask].length : c->run_args.buffer_size;        /* - headroom */
1505       src_left = size;
1506
1507       while (src_left)
1508         {
1509           if (dst_left == 0)
1510             {
1511               if (count && ns)
1512                 {
1513                   slot++;
1514                   *count_out += 1;
1515                   mq->alloc_bufs++;
1516                   ns--;
1517                   count--;
1518
1519                   ring->desc[b0->desc_index & mask].flags |=
1520                     MEMIF_DESC_FLAG_NEXT;
1521                   b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
1522
1523                   b0 = (bufs + *count_out);
1524                   b0->desc_index = slot;
1525                   dst_left = (c->args.is_master) ? ring->desc[slot & mask].length : c->run_args.buffer_size;    /* - headroom */
1526                   ring->desc[slot & mask].flags = 0;
1527                 }
1528               else
1529                 {
1530                   /* rollback allocated chain buffers */
1531                   memset (saved_b, 0, sizeof (memif_buffer_t)
1532                           * (saved_count - count + 1));
1533                   *count_out -= saved_count - count;
1534                   mq->alloc_bufs = saved_count - count;
1535                   goto no_ns;
1536                 }
1537             }
1538           b0->len = memif_min (dst_left, src_left);
1539           b0->data = memif_get_buffer (c, ring, slot & mask);
1540
1541           src_left -= b0->len;
1542           dst_left -= b0->len;
1543         }
1544
1545       slot++;
1546       *count_out += 1;
1547       mq->alloc_bufs++;
1548       ns--;
1549       count--;
1550     }
1551
1552 no_ns:
1553
1554   DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1555        mq->alloc_bufs);
1556
1557   if (count)
1558     {
1559       DBG ("ring buffer full! qid: %u", qid);
1560       err = MEMIF_ERR_NOBUF_RING;
1561     }
1562
1563   return err;
1564 }
1565
1566 int
1567 memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count)
1568 {
1569   memif_connection_t *c = (memif_connection_t *) conn;
1570   if (EXPECT_FALSE (c == NULL))
1571     return MEMIF_ERR_NOCONN;
1572   if (EXPECT_FALSE (c->fd < 0))
1573     return MEMIF_ERR_DISCONNECTED;
1574   uint8_t num =
1575     (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1576     num_m2s_rings;
1577   if (EXPECT_FALSE (qid >= num))
1578     return MEMIF_ERR_QID;
1579   libmemif_main_t *lm = &libmemif_main;
1580   memif_queue_t *mq = &c->rx_queues[qid];
1581   memif_ring_t *ring = mq->ring;
1582
1583   if (c->args.is_master)
1584     {
1585       MEMIF_MEMORY_BARRIER ();
1586       ring->tail =
1587         (ring->tail + count <=
1588          mq->last_head) ? ring->tail + count : mq->last_head;
1589     }
1590   else
1591     {
1592       uint16_t head = ring->head;
1593       uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
1594       head += ns;
1595       MEMIF_MEMORY_BARRIER ();
1596       ring->head = (ring->head + count <= head) ? ring->head + count : head;
1597     }
1598
1599   return MEMIF_ERR_SUCCESS;     /* 0 */
1600 }
1601
1602 int
1603 memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
1604                 memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
1605 {
1606   memif_connection_t *c = (memif_connection_t *) conn;
1607   if (EXPECT_FALSE (c == NULL))
1608     return MEMIF_ERR_NOCONN;
1609   if (EXPECT_FALSE (c->fd < 0))
1610     return MEMIF_ERR_DISCONNECTED;
1611   uint8_t num =
1612     (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1613     num_s2m_rings;
1614   if (EXPECT_FALSE (qid >= num))
1615     return MEMIF_ERR_QID;
1616   if (EXPECT_FALSE (!tx))
1617     return MEMIF_ERR_INVAL_ARG;
1618
1619   memif_queue_t *mq = &c->tx_queues[qid];
1620   memif_ring_t *ring = mq->ring;
1621   uint16_t slot;
1622
1623   slot = (c->args.is_master) ? ring->tail : ring->head;
1624   *tx = (count <= mq->alloc_bufs) ? count : mq->alloc_bufs;
1625
1626 #ifdef MEMIF_DBG_SHM
1627   uint16_t curr_buf = 0;
1628   uint16_t mask = (1 << mq->log2_ring_size) - 1;
1629   memif_buffer_t *b0;
1630   for (curr_buf = 0; curr_buf < count; curr_buf++)
1631     {
1632       b0 = (bufs + curr_buf);
1633       print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
1634                    ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
1635
1636     }
1637 #endif /* MEMIF_DBG_SHM */
1638
1639   MEMIF_MEMORY_BARRIER ();
1640   if (c->args.is_master)
1641     ring->tail = slot + *tx;
1642   else
1643     ring->head = slot + *tx;
1644
1645   /* zero out buffer fields so the client cant modify transmitted data */
1646   memset (bufs, 0, sizeof (memif_buffer_t) * *tx);
1647
1648   mq->alloc_bufs -= *tx;
1649
1650   if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
1651     {
1652       uint64_t a = 1;
1653       int r = write (mq->int_fd, &a, sizeof (a));
1654       if (r < 0)
1655         return MEMIF_ERR_INT_WRITE;
1656     }
1657
1658   return MEMIF_ERR_SUCCESS;     /* 0 */
1659 }
1660
1661 int
1662 memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
1663                 memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
1664 {
1665   memif_connection_t *c = (memif_connection_t *) conn;
1666   if (EXPECT_FALSE (c == NULL))
1667     return MEMIF_ERR_NOCONN;
1668   if (EXPECT_FALSE (c->fd < 0))
1669     return MEMIF_ERR_DISCONNECTED;
1670   uint8_t num =
1671     (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1672     num_m2s_rings;
1673   if (EXPECT_FALSE (qid >= num))
1674     return MEMIF_ERR_QID;
1675   if (EXPECT_FALSE (!rx))
1676     return MEMIF_ERR_INVAL_ARG;
1677
1678   memif_queue_t *mq = &c->rx_queues[qid];
1679   memif_ring_t *ring = mq->ring;
1680   uint16_t cur_slot, last_slot;
1681   uint16_t ns;
1682   uint16_t mask = (1 << mq->log2_ring_size) - 1;
1683   memif_buffer_t *b0, *b1;
1684   *rx = 0;
1685
1686   uint64_t b;
1687   ssize_t r = read (mq->int_fd, &b, sizeof (b));
1688   if ((r == -1) && (errno != EAGAIN))
1689     return memif_syscall_error_handler (errno);
1690
1691   cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
1692   last_slot = (c->args.is_master) ? ring->head : ring->tail;
1693   if (cur_slot == last_slot)
1694     return MEMIF_ERR_SUCCESS;
1695
1696   ns = last_slot - cur_slot;
1697
1698   while (ns && count)
1699     {
1700       b0 = (bufs + *rx);
1701
1702       b0->desc_index = cur_slot;
1703       b0->data = memif_get_buffer (c, ring, cur_slot & mask);
1704       b0->len = ring->desc[cur_slot & mask].length;
1705       /* slave resets buffer length */
1706       if (c->args.is_master == 0)
1707         {
1708           ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
1709         }
1710       if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
1711         {
1712           b0->flags = MEMIF_BUFFER_FLAG_NEXT;
1713           ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
1714         }
1715
1716 #ifdef MEMIF_DBG_SHM
1717       print_bytes (b0->data, b0->len, DBG_RX_BUF);
1718 #endif /* MEMIF_DBG_SHM */
1719       ns--;
1720       *rx += 1;
1721
1722       count--;
1723       cur_slot++;
1724     }
1725
1726   if (c->args.is_master)
1727     mq->last_head = cur_slot;
1728   else
1729     mq->last_tail = cur_slot;
1730
1731   if (ns)
1732     {
1733       DBG ("not enough buffers!");
1734       return MEMIF_ERR_NOBUF;
1735     }
1736
1737   return MEMIF_ERR_SUCCESS;     /* 0 */
1738 }
1739
1740 int
1741 memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
1742                    char *buf, ssize_t buflen)
1743 {
1744   libmemif_main_t *lm = &libmemif_main;
1745   memif_connection_t *c = (memif_connection_t *) conn;
1746   if (c == NULL)
1747     return MEMIF_ERR_NOCONN;
1748
1749   int err = MEMIF_ERR_SUCCESS, i;
1750   ssize_t l0, l1, total_l;
1751   l0 = 0;
1752
1753   l1 = strlen ((char *) c->args.interface_name);
1754   if (l0 + l1 < buflen)
1755     {
1756       md->if_name = strcpy (buf + l0, (char *) c->args.interface_name);
1757       l0 += l1 + 1;
1758     }
1759   else
1760     err = MEMIF_ERR_NOBUF_DET;
1761
1762   l1 = strlen ((char *) lm->app_name);
1763   if (l0 + l1 < buflen)
1764     {
1765       md->inst_name = strcpy (buf + l0, (char *) lm->app_name);
1766       l0 += l1 + 1;
1767     }
1768   else
1769     err = MEMIF_ERR_NOBUF_DET;
1770
1771   l1 = strlen ((char *) c->remote_if_name);
1772   if (l0 + l1 < buflen)
1773     {
1774       md->remote_if_name = strcpy (buf + l0, (char *) c->remote_if_name);
1775       l0 += l1 + 1;
1776     }
1777   else
1778     err = MEMIF_ERR_NOBUF_DET;
1779
1780   l1 = strlen ((char *) c->remote_name);
1781   if (l0 + l1 < buflen)
1782     {
1783       md->remote_inst_name = strcpy (buf + l0, (char *) c->remote_name);
1784       l0 += l1 + 1;
1785     }
1786   else
1787     err = MEMIF_ERR_NOBUF_DET;
1788
1789   md->id = c->args.interface_id;
1790
1791   if (c->args.secret)
1792     {
1793       l1 = strlen ((char *) c->args.secret);
1794       if (l0 + l1 < buflen)
1795         {
1796           md->secret = strcpy (buf + l0, (char *) c->args.secret);
1797           l0 += l1 + 1;
1798         }
1799       else
1800         err = MEMIF_ERR_NOBUF_DET;
1801     }
1802
1803   md->role = (c->args.is_master) ? 0 : 1;
1804   md->mode = c->args.mode;
1805
1806   l1 = strlen ((char *) c->args.socket_filename);
1807   if (l0 + l1 < buflen)
1808     {
1809       md->socket_filename =
1810         strcpy (buf + l0, (char *) c->args.socket_filename);
1811       l0 += l1 + 1;
1812     }
1813   else
1814     err = MEMIF_ERR_NOBUF_DET;
1815
1816   md->rx_queues_num =
1817     (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1818     num_m2s_rings;
1819
1820   l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
1821   if (l0 + l1 <= buflen)
1822     {
1823       md->rx_queues = (memif_queue_details_t *) buf + l0;
1824       l0 += l1;
1825     }
1826   else
1827     err = MEMIF_ERR_NOBUF_DET;
1828
1829   for (i = 0; i < md->rx_queues_num; i++)
1830     {
1831       md->rx_queues[i].qid = i;
1832       md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
1833       md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
1834       md->rx_queues[i].head = c->rx_queues[i].ring->head;
1835       md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
1836       md->rx_queues[i].buffer_size = c->run_args.buffer_size;
1837     }
1838
1839   md->tx_queues_num =
1840     (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1841     num_s2m_rings;
1842
1843   l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
1844   if (l0 + l1 <= buflen)
1845     {
1846       md->tx_queues = (memif_queue_details_t *) buf + l0;
1847       l0 += l1;
1848     }
1849   else
1850     err = MEMIF_ERR_NOBUF_DET;
1851
1852   for (i = 0; i < md->tx_queues_num; i++)
1853     {
1854       md->tx_queues[i].qid = i;
1855       md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
1856       md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
1857       md->tx_queues[i].head = c->tx_queues[i].ring->head;
1858       md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
1859       md->tx_queues[i].buffer_size = c->run_args.buffer_size;
1860     }
1861
1862   md->link_up_down = (c->fd > 0) ? 1 : 0;
1863
1864   return err;                   /* 0 */
1865 }
1866
1867 int
1868 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
1869 {
1870   memif_connection_t *c = (memif_connection_t *) conn;
1871   *efd = -1;
1872   if (c == NULL)
1873     return MEMIF_ERR_NOCONN;
1874   if (c->fd < 0)
1875     return MEMIF_ERR_DISCONNECTED;
1876   uint8_t num =
1877     (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1878     num_m2s_rings;
1879   if (qid >= num)
1880     return MEMIF_ERR_QID;
1881
1882   *efd = c->rx_queues[qid].int_fd;
1883
1884   return MEMIF_ERR_SUCCESS;
1885 }
1886
1887 int
1888 memif_cleanup ()
1889 {
1890   libmemif_main_t *lm = &libmemif_main;
1891   if (lm->control_list)
1892     lm->free (lm->control_list);
1893   lm->control_list = NULL;
1894   if (lm->interrupt_list)
1895     lm->free (lm->interrupt_list);
1896   lm->interrupt_list = NULL;
1897   if (lm->listener_list)
1898     lm->free (lm->listener_list);
1899   lm->listener_list = NULL;
1900   if (lm->pending_list)
1901     lm->free (lm->pending_list);
1902   lm->pending_list = NULL;
1903   if (poll_cancel_fd != -1)
1904     close (poll_cancel_fd);
1905
1906   return MEMIF_ERR_SUCCESS;     /* 0 */
1907 }