967e033cda36f0603c3b6fb810270304262a652b
[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 #define _GNU_SOURCE
19 #include <stdint.h>
20 #include <net/if.h>
21 #include <sys/types.h>
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <sys/uio.h>
27 #include <sys/mman.h>
28 #include <sys/prctl.h>
29 #include <inttypes.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <netdb.h>
33 #include <linux/ip.h>
34 #include <linux/icmp.h>
35 #include <arpa/inet.h>
36 #include <stdlib.h>
37 #include <netinet/if_ether.h>
38 #include <net/if_arp.h>
39 #include <asm/byteorder.h>
40 #include <byteswap.h>
41 #include <string.h>
42 #include <errno.h>
43 #include <sys/stat.h>
44 #include <sys/eventfd.h>
45 #include <sys/timerfd.h>
46 #include <sys/epoll.h>
47 #include <signal.h>
48 #include <linux/memfd.h>
49
50 /* memif protocol msg, ring and descriptor definitions */
51 #include <memif.h>
52 /* memif api */
53 #include <libmemif.h>
54 /* socket messaging functions */
55 #include <socket.h>
56 /* private structs and functions */
57 #include <memif_private.h>
58
59 #define ERRLIST_LEN 40
60 #define MAX_ERRBUF_LEN 256
61
62 #if __x86_x64__
63 #define MEMIF_MEMORY_BARRIER() __builtin_ia32_sfence ()
64 #else
65 #define MEMIF_MEMORY_BARRIER() __sync_synchronize ()
66 #endif /* __x86_x64__ */
67
68 libmemif_main_t libmemif_main;
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_CONNREFUSED */
77   "Connection refused",
78   /* MEMIF_ERR_ACCES */
79   "Permission to resource denied.",
80   /* MEMIF_ERR_NO_FILE */
81   "Socket file does not exist",
82   /* MEMIF_ERR_FILE_LIMIT */
83   "System limit on total numer of open files reached.",
84   /* MEMIF_ERR_PROC_FILE_LIMIT */
85   "Per-process limit on total number of open files reached.",
86   /* MEMIF_ERR_ALREADY */
87   "Connection already requested.",
88   /* MEMIF_ERR_AGAIN */
89   "File descriptor refers to file other than socket, or operation would block.",
90   /* MEMIF_ERR_BAD_FD */
91   "Bad file descriptor.",
92   /* MEMIF_ERR_NOMEM */
93   "Out of memory.",
94   /* MEMIF_ERR_INVAL_ARG */
95   "Invalid argument.",
96   /* MEMIF_ERR_NOCONN */
97   "Memif connection handle does not point to existing connection",
98   /* MEMIF_ERR_CONN */
99   "Memif connection handle points to existing connection",
100   /* MEMIF_ERR_CB_FDUPDATE */
101   "Callback memif_control_fd_update_t returned error",
102   /* MEMIF_ERR_FILE_NOT_SOCK */
103   "File specified by socket filename exists and is not socket.",
104   /* MEMIF_ERR_NO_SHMFD */
105   "Missing shared memory file descriptor. (internal error)",
106   /* MEMIF_ERR_COOKIE */
107   "Invalid cookie on ring. (internal error)",
108   /* MEMIF_ERR_NOBUF_RING */
109   "Ring buffer full.",
110   /* MEMIF_ERR_NOBUF */
111   "Not enough memif buffers. There are unreceived data in shared memory.",
112   /* MEMIF_ERR_NOBUF_DET */
113   "Not enough space for memif details in supplied buffer. String data might be malformed.",
114   /* MEMIF_ERR_INT_WRITE */
115   "Send interrupt error.",
116   /* MEMIF_ERR_MFMSG */
117   "Malformed message received on control channel.",
118   /* MEMIF_ERR_QID */
119   "Invalid queue id",
120   /* MEMIF_ERR_PROTO */
121   "Incompatible memory interface protocol version.",
122   /* MEMIF_ERR_ID */
123   "Unmatched interface id.",
124   /* MEMIF_ERR_ACCSLAVE */
125   "Slave cannot accept connection request.",
126   /* MEMIF_ERR_ALRCONN */
127   "Interface is already connected.",
128   /* MEMIF_ERR_MODE */
129   "Mode mismatch.",
130   /* MEMIF_ERR_SECRET */
131   "Secret mismatch.",
132   /* MEMIF_ERR_NOSECRET */
133   "Secret required.",
134   /* MEMIF_ERR_MAXREG */
135   "Limit on total number of regions reached.",
136   /* MEMIF_ERR_MAXRING */
137   "Limit on total number of ring reached.",
138   /* MEMIF_ERR_NO_INTFD */
139   "Missing interrupt file descriptor. (internal error)",
140   /* MEMIF_ERR_DISCONNECT */
141   "Interface received disconnect request.",
142   /* MEMIF_ERR_DISCONNECTED */
143   "Interface is disconnected.",
144   /* MEMIF_ERR_UNKNOWN_MSG */
145   "Unknown message type received on control channel. (internal error)",
146   /* MEMIF_ERR_POLL_CANCEL */
147   "Memif event polling was canceled.",
148   /* MEMIF_ERR_MAX_RING */
149   "Maximum log2 ring size is 15",
150   /* MEMIF_ERR_PRIVHDR */
151   "Private headers not supported."
152 };
153
154 #define MEMIF_ERR_UNDEFINED "undefined error"
155
156 char *
157 memif_strerror (int err_code)
158 {
159   if (err_code >= ERRLIST_LEN)
160     {
161       strlcpy (memif_buf, MEMIF_ERR_UNDEFINED, sizeof (memif_buf));
162     }
163   else
164     {
165       strlcpy (memif_buf, memif_errlist[err_code], sizeof (memif_buf));
166     }
167   return memif_buf;
168 }
169
170 uint16_t
171 memif_get_version ()
172 {
173   return MEMIF_VERSION;
174 }
175
176 #define DBG_TX_BUF (0)
177 #define DBG_RX_BUF (1)
178
179 #ifdef MEMIF_DBG_SHM
180 static void
181 print_bytes (void *data, uint16_t len, uint8_t q)
182 {
183   if (q == DBG_TX_BUF)
184     printf ("\nTX:\n\t");
185   else
186     printf ("\nRX:\n\t");
187   int i;
188   for (i = 0; i < len; i++)
189     {
190       if (i % 8 == 0)
191         printf ("\n%d:\t", i);
192       printf ("%02X ", ((uint8_t *) (data))[i]);
193     }
194   printf ("\n\n");
195 }
196 #endif /* MEMIF_DBG_SHM */
197
198 int
199 memif_syscall_error_handler (int err_code)
200 {
201   DBG ("%s", strerror (err_code));
202
203   if (err_code == 0)
204     return MEMIF_ERR_SUCCESS;
205   if (err_code == EACCES)
206     return MEMIF_ERR_ACCES;
207   if (err_code == ENFILE)
208     return MEMIF_ERR_FILE_LIMIT;
209   if (err_code == EMFILE)
210     return MEMIF_ERR_PROC_FILE_LIMIT;
211   if (err_code == ENOMEM)
212     return MEMIF_ERR_NOMEM;
213 /* connection refused if master does not exist
214     this error would spam the user until master was created */
215 /*
216   if (err_code == ECONNREFUSED)
217     return MEMIF_ERR_SUCCESS;
218 */
219   if (err_code == ECONNREFUSED)
220     return MEMIF_ERR_CONNREFUSED;
221   if (err_code == EALREADY)
222     return MEMIF_ERR_ALREADY;
223   if (err_code == EAGAIN)
224     return MEMIF_ERR_AGAIN;
225   if (err_code == EBADF)
226     return MEMIF_ERR_BAD_FD;
227   if (err_code == ENOENT)
228     return MEMIF_ERR_NO_FILE;
229
230   /* other syscall errors */
231   return MEMIF_ERR_SYSCALL;
232 }
233
234 /* Always valid */
235 libmemif_main_t *
236 get_libmemif_main (memif_socket_t * ms)
237 {
238   if (ms != NULL && ms->lm != NULL)
239     return ms->lm;
240   return &libmemif_main;
241 }
242
243 static int
244 memif_add_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
245 {
246   if (fd < 0)
247     {
248       DBG ("invalid fd %d", fd);
249       return -1;
250     }
251   struct epoll_event evt;
252   memset (&evt, 0, sizeof (evt));
253   evt.events = events;
254   evt.data.fd = fd;
255   if (epoll_ctl (lm->epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
256     {
257       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
258       return -1;
259     }
260   DBG ("fd %d added to epoll", fd);
261   return 0;
262 }
263
264 static int
265 memif_mod_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
266 {
267   if (fd < 0)
268     {
269       DBG ("invalid fd %d", fd);
270       return -1;
271     }
272   struct epoll_event evt;
273   memset (&evt, 0, sizeof (evt));
274   evt.events = events;
275   evt.data.fd = fd;
276   if (epoll_ctl (lm->epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
277     {
278       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
279       return -1;
280     }
281   DBG ("fd %d modified on epoll", fd);
282   return 0;
283 }
284
285 static int
286 memif_del_epoll_fd (libmemif_main_t * lm, int fd)
287 {
288   if (fd < 0)
289     {
290       DBG ("invalid fd %d", fd);
291       return -1;
292     }
293   struct epoll_event evt;
294   memset (&evt, 0, sizeof (evt));
295   if (epoll_ctl (lm->epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
296     {
297       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
298       return -1;
299     }
300   DBG ("fd %d removed from epoll", fd);
301   return 0;
302 }
303
304 int
305 memif_control_fd_update (int fd, uint8_t events, void *private_ctx)
306 {
307   libmemif_main_t *lm;
308
309   lm = (private_ctx == NULL) ? &libmemif_main : (libmemif_main_t *) private_ctx;
310
311   if (events & MEMIF_FD_EVENT_DEL)
312     return memif_del_epoll_fd (lm, fd);
313
314   uint32_t evt = 0;
315   if (events & MEMIF_FD_EVENT_READ)
316     evt |= EPOLLIN;
317   if (events & MEMIF_FD_EVENT_WRITE)
318     evt |= EPOLLOUT;
319
320   if (events & MEMIF_FD_EVENT_MOD)
321     return memif_mod_epoll_fd (lm, fd, evt);
322
323   return memif_add_epoll_fd (lm, fd, evt);
324 }
325
326 int
327 add_list_elt (libmemif_main_t * lm, memif_list_elt_t * e,
328               memif_list_elt_t ** list, uint16_t * len)
329 {
330   memif_list_elt_t *tmp;
331   int i;
332
333   for (i = 0; i < *len; i++)
334     {
335       if ((*list)[i].data_struct == NULL)
336         {
337           (*list)[i].key = e->key;
338           (*list)[i].data_struct = e->data_struct;
339           return i;
340         }
341     }
342
343   tmp = lm->realloc (*list, sizeof (memif_list_elt_t) * *len * 2);
344   if (tmp == NULL)
345     return -1;
346
347   for (i = *len; i < *len * 2; i++)
348     {
349       tmp[i].key = -1;
350       tmp[i].data_struct = NULL;
351     }
352
353   tmp[*len].key = e->key;
354   tmp[*len].data_struct = e->data_struct;
355   i = *len;
356   *len = *len * 2;
357   *list = tmp;
358
359   return i;
360 }
361
362 int
363 get_list_elt (memif_list_elt_t ** e, memif_list_elt_t * list, uint16_t len,
364               int key)
365 {
366   int i;
367   if (key == -1)
368     {
369       *e = NULL;
370       return -1;
371     }
372
373   for (i = 0; i < len; i++)
374     {
375       if (list[i].key == key)
376         {
377           *e = &list[i];
378           return 0;
379         }
380     }
381   *e = NULL;
382   return -1;
383 }
384
385 /* does not free memory, only marks element as free */
386 int
387 free_list_elt (memif_list_elt_t * list, uint16_t len, int key)
388 {
389   int i;
390   for (i = 0; i < len; i++)
391     {
392       if (list[i].key == key)
393         {
394           list[i].key = -1;
395           list[i].data_struct = NULL;
396           return 0;
397         }
398     }
399
400   return -1;
401 }
402
403 int
404 free_list_elt_ctx (memif_list_elt_t * list, uint16_t len,
405                    memif_connection_t * ctx)
406 {
407   int i;
408   for (i = 0; i < len; i++)
409     {
410       if (list[i].key == -1)
411         {
412           if (list[i].data_struct == ctx)
413             {
414               list[i].data_struct = NULL;
415               return 0;
416             }
417         }
418     }
419
420   return -1;
421 }
422
423 static void
424 memif_control_fd_update_register (libmemif_main_t * lm,
425                                   memif_control_fd_update_t * cb)
426 {
427   lm->control_fd_update = cb;
428 }
429
430 void
431 memif_register_external_region (memif_add_external_region_t * ar,
432                                 memif_get_external_region_addr_t * gr,
433                                 memif_del_external_region_t * dr,
434                                 memif_get_external_buffer_offset_t * go)
435 {
436   libmemif_main_t *lm = &libmemif_main;
437   lm->add_external_region = ar;
438   lm->get_external_region_addr = gr;
439   lm->del_external_region = dr;
440   lm->get_external_buffer_offset = go;
441 }
442
443 static void
444 memif_alloc_register (libmemif_main_t * lm, memif_alloc_t * ma)
445 {
446   lm->alloc = ma;
447 }
448
449 static void
450 memif_realloc_register (libmemif_main_t * lm, memif_realloc_t * mr)
451 {
452   lm->realloc = mr;
453 }
454
455 static void
456 memif_free_register (libmemif_main_t * lm, memif_free_t * mf)
457 {
458   lm->free = mf;
459 }
460
461 int
462 memif_set_connection_request_timer (struct itimerspec timer)
463 {
464   libmemif_main_t *lm = &libmemif_main;
465   int err = MEMIF_ERR_SUCCESS;
466
467   lm->arm = timer;
468
469   /* overwrite timer, if already armed */
470   if (lm->disconn_slaves != 0)
471     {
472       if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
473         {
474           err = memif_syscall_error_handler (errno);
475         }
476     }
477   return err;
478 }
479
480 int
481 memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
482             memif_alloc_t * memif_alloc, memif_realloc_t * memif_realloc,
483             memif_free_t * memif_free)
484 {
485   int err = MEMIF_ERR_SUCCESS;  /* 0 */
486   libmemif_main_t *lm = &libmemif_main;
487   memset (lm, 0, sizeof (libmemif_main_t));
488
489   /* register custom memory management */
490   if (memif_alloc != NULL)
491     {
492       memif_alloc_register (lm, memif_alloc);
493     }
494   else
495     memif_alloc_register (lm, malloc);
496
497   if (memif_realloc != NULL)
498     {
499       memif_realloc_register (lm, memif_realloc);
500     }
501   else
502     memif_realloc_register (lm, realloc);
503
504   if (memif_free != NULL)
505     memif_free_register (lm, memif_free);
506   else
507     memif_free_register (lm, free);
508
509   if (app_name != NULL)
510     {
511       strlcpy ((char *) lm->app_name, app_name, sizeof (lm->app_name));
512     }
513   else
514     {
515       strlcpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
516                sizeof (lm->app_name));
517     }
518
519   lm->poll_cancel_fd = -1;
520   /* register control fd update callback */
521   if (on_control_fd_update != NULL)
522     memif_control_fd_update_register (lm, on_control_fd_update);
523   else
524     {
525       lm->epfd = epoll_create (1);
526       memif_control_fd_update_register (lm, memif_control_fd_update);
527       if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
528         {
529           err = errno;
530           DBG ("eventfd: %s", strerror (err));
531           return memif_syscall_error_handler (err);
532         }
533       lm->control_fd_update (lm->poll_cancel_fd, MEMIF_FD_EVENT_READ, lm->private_ctx);
534       DBG ("libmemif event polling initialized");
535     }
536
537   lm->control_list_len = 2;
538   lm->interrupt_list_len = 2;
539   lm->socket_list_len = 1;
540   lm->pending_list_len = 1;
541
542   lm->control_list =
543     lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
544   if (lm->control_list == NULL)
545     {
546       err = MEMIF_ERR_NOMEM;
547       goto error;
548     }
549   lm->interrupt_list =
550     lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
551   if (lm->interrupt_list == NULL)
552     {
553       err = MEMIF_ERR_NOMEM;
554       goto error;
555     }
556   lm->socket_list =
557     lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
558   if (lm->socket_list == NULL)
559     {
560       err = MEMIF_ERR_NOMEM;
561       goto error;
562     }
563   lm->pending_list =
564     lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
565   if (lm->pending_list == NULL)
566     {
567       err = MEMIF_ERR_NOMEM;
568       goto error;
569     }
570
571   int i;
572   for (i = 0; i < lm->control_list_len; i++)
573     {
574       lm->control_list[i].key = -1;
575       lm->control_list[i].data_struct = NULL;
576     }
577   for (i = 0; i < lm->interrupt_list_len; i++)
578     {
579       lm->interrupt_list[i].key = -1;
580       lm->interrupt_list[i].data_struct = NULL;
581     }
582   for (i = 0; i < lm->socket_list_len; i++)
583     {
584       lm->socket_list[i].key = -1;
585       lm->socket_list[i].data_struct = NULL;
586     }
587   for (i = 0; i < lm->pending_list_len; i++)
588     {
589       lm->pending_list[i].key = -1;
590       lm->pending_list[i].data_struct = NULL;
591     }
592
593   lm->disconn_slaves = 0;
594
595   lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
596   if (lm->timerfd < 0)
597     {
598       err = memif_syscall_error_handler (errno);
599       goto error;
600     }
601
602   lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
603   lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
604   lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
605   lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
606
607   if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ, lm->private_ctx) < 0)
608     {
609       DBG ("callback type memif_control_fd_update_t error!");
610       err = MEMIF_ERR_CB_FDUPDATE;
611       goto error;
612     }
613
614   /* Create default socket */
615   err = memif_create_socket ((memif_socket_handle_t *) &
616                              lm->default_socket,
617                              MEMIF_DEFAULT_SOCKET_PATH, NULL);
618   if (err != MEMIF_ERR_SUCCESS)
619     goto error;
620
621   return err;
622
623 error:
624   memif_cleanup ();
625   return err;
626 }
627
628 static inline memif_ring_t *
629 memif_get_ring (memif_connection_t * conn, memif_ring_type_t type,
630                 uint16_t ring_num)
631 {
632   if (&conn->regions[0] == NULL)
633     return NULL;
634   void *p = conn->regions[0].addr;
635   int ring_size =
636     sizeof (memif_ring_t) +
637     sizeof (memif_desc_t) * (1 << conn->run_args.log2_ring_size);
638   p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
639
640   return (memif_ring_t *) p;
641 }
642
643 int
644 memif_set_rx_mode (memif_conn_handle_t c, memif_rx_mode_t rx_mode,
645                    uint16_t qid)
646 {
647   memif_connection_t *conn = (memif_connection_t *) c;
648   if (conn == NULL)
649     return MEMIF_ERR_NOCONN;
650   uint8_t num =
651     (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
652     run_args.num_m2s_rings;
653   if (qid >= num)
654     return MEMIF_ERR_QID;
655
656   conn->rx_queues[qid].ring->flags = rx_mode;
657   DBG ("rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
658   return MEMIF_ERR_SUCCESS;
659 }
660
661 static int
662 memif_socket_start_listening (memif_socket_t * ms)
663 {
664   libmemif_main_t *lm = get_libmemif_main (ms);
665   memif_list_elt_t elt;
666   struct stat file_stat;
667   struct sockaddr_un un = { 0 };
668   int on = 1;
669   int err = MEMIF_ERR_SUCCESS;
670
671   if (ms->type == MEMIF_SOCKET_TYPE_CLIENT)
672     return MEMIF_ERR_INVAL_ARG;
673
674   /* check if file exists */
675   if (stat ((char *) ms->filename, &file_stat) == 0)
676     {
677       if (S_ISSOCK (file_stat.st_mode))
678         unlink ((char *) ms->filename);
679       else
680         return memif_syscall_error_handler (errno);
681     }
682
683   ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
684   if (ms->fd < 0)
685     {
686       err = memif_syscall_error_handler (errno);
687       goto error;
688     }
689
690   DBG ("socket %d created", ms->fd);
691   un.sun_family = AF_UNIX;
692   strlcpy ((char *) un.sun_path, (char *) ms->filename, sizeof (un.sun_path));
693   if (setsockopt (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
694     {
695       err = memif_syscall_error_handler (errno);
696       goto error;
697     }
698   if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
699     {
700       err = memif_syscall_error_handler (errno);
701       goto error;
702     }
703   if (listen (ms->fd, 1) < 0)
704     {
705       err = memif_syscall_error_handler (errno);
706       goto error;
707     }
708   if (stat ((char *) ms->filename, &file_stat) < 0)
709     {
710       err = memif_syscall_error_handler (errno);
711       goto error;
712     }
713
714   /* add socket to libmemif main */
715   elt.key = ms->fd;
716   elt.data_struct = ms;
717   add_list_elt (lm, &elt, &lm->socket_list, &lm->socket_list_len);
718   /* if lm->private_ctx == lm event polling is done by libmemif */
719   lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_READ, lm->private_ctx);
720
721   ms->type = MEMIF_SOCKET_TYPE_LISTENER;
722
723   return err;
724
725 error:
726   if (ms->fd > 0)
727     {
728       close (ms->fd);
729       ms->fd = -1;
730     }
731   return err;
732 }
733
734 int
735 memif_create_socket (memif_socket_handle_t * sock, const char *filename,
736                      void *private_ctx)
737 {
738   libmemif_main_t *lm = &libmemif_main;
739   memif_socket_t *ms = (memif_socket_t *) * sock;
740   int i, err = MEMIF_ERR_SUCCESS;
741
742   for (i = 0; i < lm->socket_list_len; i++)
743     {
744       if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
745         {
746           if (strncmp ((char *) ms->filename, filename,
747                        strlen ((char *) ms->filename)) == 0)
748             return MEMIF_ERR_INVAL_ARG;
749         }
750     }
751
752   /* allocate memif_socket_t */
753   ms = NULL;
754   ms = lm->alloc (sizeof (memif_socket_t));
755   if (ms == NULL)
756     {
757       err = MEMIF_ERR_NOMEM;
758       goto error;
759     }
760   memset (ms, 0, sizeof (memif_socket_t));
761   /* set filename */
762   memset (ms->filename, 0, sizeof (ms->filename));
763   strlcpy ((char *) ms->filename, filename, sizeof (ms->filename));
764
765   ms->type = MEMIF_SOCKET_TYPE_NONE;
766
767   ms->interface_list_len = 1;
768   ms->interface_list =
769     lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
770   if (ms->interface_list == NULL)
771     {
772       err = MEMIF_ERR_NOMEM;
773       goto error;
774     }
775   ms->interface_list[0].key = -1;
776   ms->interface_list[0].data_struct = NULL;
777
778   *sock = ms;
779
780   return err;
781
782 error:
783   if (ms != NULL)
784     {
785       if (ms->fd > 0)
786         {
787           close (ms->fd);
788           ms->fd = -1;
789         }
790       if (ms->interface_list != NULL)
791         {
792           lm->free (ms->interface_list);
793           ms->interface_list = NULL;
794           ms->interface_list_len = 0;
795         }
796       lm->free (ms);
797       *sock = ms = NULL;
798     }
799   return err;
800 }
801
802
803 int
804 memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
805               memif_connection_update_t * on_connect,
806               memif_connection_update_t * on_disconnect,
807               memif_interrupt_t * on_interrupt, void *private_ctx)
808 {
809   libmemif_main_t *lm = get_libmemif_main (args->socket);
810   int err, index = 0;
811   memif_list_elt_t elt;
812   memif_connection_t *conn = (memif_connection_t *) * c;
813   memif_socket_t *ms;
814
815   if (conn != NULL)
816     {
817       DBG ("This handle already points to existing memif.");
818       return MEMIF_ERR_CONN;
819     }
820
821   conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
822   if (conn == NULL)
823     {
824       err = MEMIF_ERR_NOMEM;
825       goto error;
826     }
827   memset (conn, 0, sizeof (memif_connection_t));
828
829   conn->args.interface_id = args->interface_id;
830
831   if (args->log2_ring_size == 0)
832     args->log2_ring_size = MEMIF_DEFAULT_LOG2_RING_SIZE;
833   else if (args->log2_ring_size > MEMIF_MAX_LOG2_RING_SIZE)
834     {
835       err = MEMIF_ERR_MAX_RING;
836       goto error;
837     }
838   if (args->buffer_size == 0)
839     args->buffer_size = MEMIF_DEFAULT_BUFFER_SIZE;
840   if (args->num_s2m_rings == 0)
841     args->num_s2m_rings = MEMIF_DEFAULT_TX_QUEUES;
842   if (args->num_m2s_rings == 0)
843     args->num_m2s_rings = MEMIF_DEFAULT_RX_QUEUES;
844
845   conn->args.num_s2m_rings = args->num_s2m_rings;
846   conn->args.num_m2s_rings = args->num_m2s_rings;
847   conn->args.buffer_size = args->buffer_size;
848   conn->args.log2_ring_size = args->log2_ring_size;
849   conn->args.is_master = args->is_master;
850   conn->args.mode = args->mode;
851   conn->msg_queue = NULL;
852   conn->regions = NULL;
853   conn->tx_queues = NULL;
854   conn->rx_queues = NULL;
855   conn->fd = -1;
856   conn->on_connect = on_connect;
857   conn->on_disconnect = on_disconnect;
858   conn->on_interrupt = on_interrupt;
859   conn->private_ctx = private_ctx;
860   memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
861
862   strlcpy ((char *) conn->args.interface_name, (char *) args->interface_name,
863            sizeof (conn->args.interface_name));
864
865   if ((strlen ((char *) args->secret)) > 0)
866     strlcpy ((char *) conn->args.secret, (char *) args->secret,
867              sizeof (conn->args.secret));
868
869   if (args->socket != NULL)
870     conn->args.socket = args->socket;
871   else if (lm->default_socket != NULL)
872     conn->args.socket = lm->default_socket;
873   else
874     {
875       err = MEMIF_ERR_INVAL_ARG;
876       goto error;
877     }
878
879   ms = (memif_socket_t *) conn->args.socket;
880
881   if ((conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_CLIENT) ||
882       (!conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_LISTENER))
883     {
884       err = MEMIF_ERR_INVAL_ARG;
885       goto error;
886     }
887
888   elt.key = conn->args.interface_id;
889   elt.data_struct = conn;
890   add_list_elt (lm, &elt, &ms->interface_list, &ms->interface_list_len);
891   ms->use_count++;
892
893   if (conn->args.is_master)
894     {
895       if (ms->type == MEMIF_SOCKET_TYPE_NONE)
896         {
897           err = memif_socket_start_listening (ms);
898           if (err != MEMIF_ERR_SUCCESS)
899             goto error;
900         }
901     }
902   else
903     {
904       elt.key = -1;
905       elt.data_struct = conn;
906       if ((index =
907            add_list_elt (lm, &elt, &lm->control_list,
908                          &lm->control_list_len)) < 0)
909         {
910           err = MEMIF_ERR_NOMEM;
911           goto error;
912         }
913
914       conn->index = index;
915
916       /* try connecting to master */
917       err = memif_request_connection (conn);
918       if ((err != MEMIF_ERR_SUCCESS) && (lm->disconn_slaves == 0))
919         {
920           /* connection failed, arm reconnect timer (if not armed) */
921           if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
922             {
923               err = memif_syscall_error_handler (errno);
924               goto error;
925             }
926         }
927       lm->disconn_slaves++;
928     }
929
930   *c = conn;
931
932   return 0;
933
934 error:
935   if (conn != NULL)
936     lm->free (conn);
937   *c = conn = NULL;
938   return err;
939 }
940
941 int
942 memif_request_connection (memif_conn_handle_t c)
943 {
944   memif_connection_t *conn = (memif_connection_t *) c;
945   libmemif_main_t *lm;
946   memif_socket_t *ms;
947   int err = MEMIF_ERR_SUCCESS;
948   int sockfd = -1;
949   struct sockaddr_un sun;
950
951   if (conn == NULL)
952     return MEMIF_ERR_NOCONN;
953
954   ms = (memif_socket_t *) conn->args.socket;
955   lm = get_libmemif_main (ms);
956
957
958   if (conn->args.is_master || ms->type == MEMIF_SOCKET_TYPE_LISTENER)
959     return MEMIF_ERR_INVAL_ARG;
960   if (conn->fd > 0)
961     return MEMIF_ERR_ALRCONN;
962
963   sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
964   if (sockfd < 0)
965     {
966       err = memif_syscall_error_handler (errno);
967       goto error;
968     }
969
970   sun.sun_family = AF_UNIX;
971
972   strlcpy (sun.sun_path, (char *) ms->filename, sizeof (sun.sun_path));
973
974   if (connect (sockfd, (struct sockaddr *) &sun,
975                sizeof (struct sockaddr_un)) == 0)
976     {
977       conn->fd = sockfd;
978       conn->read_fn = memif_conn_fd_read_ready;
979       conn->write_fn = memif_conn_fd_write_ready;
980       conn->error_fn = memif_conn_fd_error;
981
982       lm->control_list[conn->index].key = conn->fd;
983       lm->control_fd_update (sockfd,
984                              MEMIF_FD_EVENT_READ |
985                              MEMIF_FD_EVENT_WRITE, lm->private_ctx);
986
987       lm->disconn_slaves--;
988       if (lm->disconn_slaves == 0)
989         {
990           if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
991             {
992               err = memif_syscall_error_handler (errno);
993               return err;
994             }
995         }
996     }
997   else
998     {
999       err = memif_syscall_error_handler (errno);
1000       strcpy ((char *) conn->remote_disconnect_string, memif_strerror (err));
1001       goto error;
1002     }
1003
1004   ms->type = MEMIF_SOCKET_TYPE_CLIENT;
1005
1006   return err;
1007
1008 error:
1009   if (sockfd > 0)
1010     close (sockfd);
1011   sockfd = -1;
1012   return err;
1013 }
1014
1015 int
1016 memif_control_fd_handler (int fd, uint8_t events)
1017 {
1018   int i, err = MEMIF_ERR_SUCCESS;       /* 0 */
1019   uint16_t num;
1020   memif_list_elt_t *e = NULL;
1021   memif_connection_t *conn;
1022   libmemif_main_t *lm = &libmemif_main;
1023   if (fd == lm->timerfd)
1024     {
1025       uint64_t b;
1026       ssize_t size;
1027       size = read (fd, &b, sizeof (b));
1028
1029       if (size == -1)
1030         goto error;
1031
1032       for (i = 0; i < lm->control_list_len; i++)
1033         {
1034           if ((lm->control_list[i].key < 0)
1035               && (lm->control_list[i].data_struct != NULL))
1036             {
1037               conn = lm->control_list[i].data_struct;
1038               if (conn->args.is_master)
1039                 continue;
1040               err = memif_request_connection (conn);
1041               if (err != MEMIF_ERR_SUCCESS)
1042                 DBG ("memif_request_connection: %s", memif_strerror (err));
1043             }
1044         }
1045     }
1046   else
1047     {
1048       get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1049       if (e != NULL)
1050         {
1051           if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1052             {
1053               num =
1054                 (((memif_connection_t *) e->data_struct)->
1055                  args.is_master) ? ((memif_connection_t *) e->
1056                                     data_struct)->run_args.
1057                 num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1058                 run_args.num_m2s_rings;
1059               for (i = 0; i < num; i++)
1060                 {
1061                   if (((memif_connection_t *) e->data_struct)->
1062                       rx_queues[i].int_fd == fd)
1063                     {
1064                       ((memif_connection_t *) e->data_struct)->
1065                         on_interrupt ((void *) e->data_struct,
1066                                       ((memif_connection_t *) e->
1067                                        data_struct)->private_ctx, i);
1068                       return MEMIF_ERR_SUCCESS;
1069                     }
1070                 }
1071             }
1072           return MEMIF_ERR_SUCCESS;
1073         }
1074       get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
1075       if (e != NULL
1076           && ((memif_socket_t *) e->data_struct)->type ==
1077           MEMIF_SOCKET_TYPE_LISTENER)
1078         {
1079           err =
1080             memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
1081           return err;
1082         }
1083
1084       get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1085       if (e != NULL)
1086         {
1087           err = memif_read_ready (lm, fd);
1088           return err;
1089         }
1090
1091       get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1092       if (e != NULL)
1093         {
1094           if (events & MEMIF_FD_EVENT_READ)
1095             {
1096               err =
1097                 ((memif_connection_t *) e->data_struct)->
1098                 read_fn (e->data_struct);
1099               if (err != MEMIF_ERR_SUCCESS)
1100                 return err;
1101             }
1102           if (events & MEMIF_FD_EVENT_WRITE)
1103             {
1104               err =
1105                 ((memif_connection_t *) e->data_struct)->
1106                 write_fn (e->data_struct);
1107               if (err != MEMIF_ERR_SUCCESS)
1108                 return err;
1109             }
1110           if (events & MEMIF_FD_EVENT_ERROR)
1111             {
1112               err =
1113                 ((memif_connection_t *) e->data_struct)->
1114                 error_fn (e->data_struct);
1115               if (err != MEMIF_ERR_SUCCESS)
1116                 return err;
1117             }
1118         }
1119     }
1120
1121   return MEMIF_ERR_SUCCESS;     /* 0 */
1122
1123 error:
1124   return err;
1125 }
1126
1127
1128 int
1129 memif_poll_event (int timeout)
1130 {
1131   libmemif_main_t *lm = &libmemif_main;
1132   struct epoll_event evt;
1133   int en = 0, err = MEMIF_ERR_SUCCESS;  /* 0 */
1134   uint32_t events = 0;
1135   uint64_t counter = 0;
1136   ssize_t r = 0;
1137   memset (&evt, 0, sizeof (evt));
1138   evt.events = EPOLLIN | EPOLLOUT;
1139   sigset_t sigset;
1140   sigemptyset (&sigset);
1141   en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
1142   if (en < 0)
1143     {
1144       err = errno;
1145       DBG ("epoll_pwait: %s", strerror (err));
1146       return memif_syscall_error_handler (err);
1147     }
1148   if (en > 0)
1149     {
1150       if (evt.data.fd == lm->poll_cancel_fd)
1151         {
1152           r = read (evt.data.fd, &counter, sizeof (counter));
1153           if (r == -1)
1154             return MEMIF_ERR_DISCONNECTED;
1155
1156           return MEMIF_ERR_POLL_CANCEL;
1157         }
1158       if (evt.events & EPOLLIN)
1159         events |= MEMIF_FD_EVENT_READ;
1160       if (evt.events & EPOLLOUT)
1161         events |= MEMIF_FD_EVENT_WRITE;
1162       if (evt.events & EPOLLERR)
1163         events |= MEMIF_FD_EVENT_ERROR;
1164       err = memif_control_fd_handler (evt.data.fd, events);
1165       return err;
1166     }
1167   return 0;
1168 }
1169
1170 int
1171 memif_cancel_poll_event ()
1172 {
1173   libmemif_main_t *lm = &libmemif_main;
1174   uint64_t counter = 1;
1175   ssize_t w = 0;
1176
1177   if (lm->poll_cancel_fd == -1)
1178     return 0;
1179   w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
1180   if (w < sizeof (counter))
1181     return MEMIF_ERR_INT_WRITE;
1182
1183   return 0;
1184 }
1185
1186 static void
1187 memif_msg_queue_free (libmemif_main_t * lm, memif_msg_queue_elt_t ** e)
1188 {
1189   if (*e == NULL)
1190     return;
1191   memif_msg_queue_free (lm, &(*e)->next);
1192   lm->free (*e);
1193   *e = NULL;
1194   return;
1195 }
1196
1197 /* send disconnect msg and close interface */
1198 int
1199 memif_disconnect_internal (memif_connection_t * c)
1200 {
1201   int err = MEMIF_ERR_SUCCESS, i;       /* 0 */
1202   memif_queue_t *mq;
1203   libmemif_main_t *lm;
1204   memif_list_elt_t *e;
1205
1206   if (c == NULL)
1207     {
1208       DBG ("no connection");
1209       return MEMIF_ERR_NOCONN;
1210     }
1211
1212   lm = get_libmemif_main (c->args.socket);
1213
1214   c->on_disconnect ((void *) c, c->private_ctx);
1215
1216   if (c->fd > 0)
1217     {
1218       memif_msg_send_disconnect (c->fd, (uint8_t *) "interface deleted", 0);
1219       lm->control_fd_update (c->fd, MEMIF_FD_EVENT_DEL, lm->private_ctx);
1220       close (c->fd);
1221     }
1222   get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
1223   if (e != NULL)
1224     {
1225       if (c->args.is_master)
1226         free_list_elt (lm->control_list, lm->control_list_len, c->fd);
1227       e->key = c->fd = -1;
1228     }
1229
1230   if (c->tx_queues != NULL)
1231     {
1232       for (i = 0; i < c->tx_queues_num; i++)
1233         {
1234           mq = &c->tx_queues[i];
1235           if (mq != NULL)
1236             {
1237               if (mq->int_fd > 0)
1238                 close (mq->int_fd);
1239               free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1240                              mq->int_fd);
1241               mq->int_fd = -1;
1242             }
1243         }
1244       lm->free (c->tx_queues);
1245       c->tx_queues = NULL;
1246     }
1247   c->tx_queues_num = 0;
1248
1249   if (c->rx_queues != NULL)
1250     {
1251       for (i = 0; i < c->rx_queues_num; i++)
1252         {
1253           mq = &c->rx_queues[i];
1254           if (mq != NULL)
1255             {
1256               if (mq->int_fd > 0)
1257                 {
1258                   if (c->on_interrupt != NULL)
1259                     lm->control_fd_update (mq->int_fd, MEMIF_FD_EVENT_DEL,
1260                                            lm->private_ctx);
1261                   close (mq->int_fd);
1262                 }
1263               free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1264                              mq->int_fd);
1265               mq->int_fd = -1;
1266             }
1267         }
1268       lm->free (c->rx_queues);
1269       c->rx_queues = NULL;
1270     }
1271   c->rx_queues_num = 0;
1272
1273   for (i = 0; i < c->regions_num; i++)
1274     {
1275       if (&c->regions[i] == NULL)
1276         continue;
1277       if (c->regions[i].is_external != 0)
1278         {
1279           lm->del_external_region (c->regions[i].addr,
1280                                    c->regions[i].region_size,
1281                                    c->regions[i].fd, c->private_ctx);
1282         }
1283       else
1284         {
1285           if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1286             return memif_syscall_error_handler (errno);
1287           if (c->regions[i].fd > 0)
1288             close (c->regions[i].fd);
1289           c->regions[i].fd = -1;
1290         }
1291     }
1292   lm->free (c->regions);
1293   c->regions = NULL;
1294   c->regions_num = 0;
1295
1296   memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
1297
1298   memif_msg_queue_free (lm, &c->msg_queue);
1299
1300   if (!(c->args.is_master))
1301     {
1302       if (lm->disconn_slaves == 0)
1303         {
1304           if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1305             {
1306               err = memif_syscall_error_handler (errno);
1307               DBG ("timerfd_settime: arm");
1308             }
1309         }
1310       lm->disconn_slaves++;
1311     }
1312
1313   return err;
1314 }
1315
1316 const char *
1317 memif_get_socket_filename (memif_socket_handle_t sock)
1318 {
1319   memif_socket_t *ms = (memif_socket_t *) sock;
1320
1321   if (ms == NULL)
1322     return NULL;
1323
1324   return (char *) ms->filename;
1325 }
1326
1327 int
1328 memif_delete_socket (memif_socket_handle_t * sock)
1329 {
1330   memif_socket_t *ms = (memif_socket_t *) * sock;
1331   libmemif_main_t *lm;
1332
1333   /* check if socket is in use */
1334   if (ms == NULL || ms->use_count > 0)
1335     return MEMIF_ERR_INVAL_ARG;
1336
1337   lm = get_libmemif_main (ms);
1338
1339   lm->free (ms->interface_list);
1340   ms->interface_list = NULL;
1341   lm->free (ms);
1342   *sock = ms = NULL;
1343
1344   return MEMIF_ERR_SUCCESS;
1345 }
1346
1347 int
1348 memif_delete (memif_conn_handle_t * conn)
1349 {
1350   memif_connection_t *c = (memif_connection_t *) * conn;
1351   libmemif_main_t *lm;
1352   memif_socket_t *ms = NULL;
1353   int err = MEMIF_ERR_SUCCESS;
1354
1355   if (c == NULL)
1356     {
1357       DBG ("no connection");
1358       return MEMIF_ERR_NOCONN;
1359     }
1360
1361   if (c->fd > 0)
1362     {
1363       DBG ("DISCONNECTING");
1364       err = memif_disconnect_internal (c);
1365       if (err == MEMIF_ERR_NOCONN)
1366         return err;
1367     }
1368
1369   lm = get_libmemif_main (c->args.socket);
1370
1371   free_list_elt_ctx (lm->control_list, lm->control_list_len, c);
1372
1373   ms = (memif_socket_t *) c->args.socket;
1374   ms->use_count--;
1375   free_list_elt (ms->interface_list, ms->interface_list_len,
1376                  c->args.interface_id);
1377   if (ms->use_count <= 0)
1378     {
1379       /* stop listening on this socket */
1380       if (ms->type == MEMIF_SOCKET_TYPE_LISTENER)
1381         {
1382           lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_DEL, lm->private_ctx);
1383           free_list_elt (lm->socket_list, lm->socket_list_len, ms->fd);
1384           close (ms->fd);
1385           ms->fd = -1;
1386         }
1387       /* socket not in use */
1388       ms->type = MEMIF_SOCKET_TYPE_NONE;
1389     }
1390
1391   if (!c->args.is_master)
1392     {
1393       lm->disconn_slaves--;
1394       if (lm->disconn_slaves <= 0)
1395         {
1396           if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1397             {
1398               err = memif_syscall_error_handler (errno);
1399               DBG ("timerfd_settime: disarm");
1400             }
1401         }
1402     }
1403
1404   lm->free (c);
1405   c = NULL;
1406
1407   *conn = c;
1408   return err;
1409 }
1410
1411 int
1412 memif_connect1 (memif_connection_t * c)
1413 {
1414   libmemif_main_t *lm;
1415   memif_region_t *mr;
1416   memif_queue_t *mq;
1417   int i;
1418
1419   if (c == NULL)
1420     return MEMIF_ERR_INVAL_ARG;
1421
1422   lm = get_libmemif_main (c->args.socket);
1423
1424   for (i = 0; i < c->regions_num; i++)
1425     {
1426       mr = &c->regions[i];
1427       if (mr != NULL)
1428         {
1429           if (!mr->addr)
1430             {
1431               if (mr->is_external)
1432                 {
1433                   if (lm->get_external_region_addr == NULL)
1434                     return MEMIF_ERR_INVAL_ARG;
1435                   mr->addr =
1436                     lm->get_external_region_addr (mr->region_size, mr->fd,
1437                                                   c->private_ctx);
1438                 }
1439               else
1440                 {
1441                   if (mr->fd < 0)
1442                     return MEMIF_ERR_NO_SHMFD;
1443
1444                   if ((mr->addr =
1445                        mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
1446                              MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
1447                     {
1448                       return memif_syscall_error_handler (errno);
1449                     }
1450                 }
1451             }
1452         }
1453     }
1454
1455   for (i = 0; i < c->rx_queues_num; i++)
1456     {
1457       mq = &c->rx_queues[i];
1458       if (mq != NULL)
1459         {
1460           mq->ring = c->regions[mq->region].addr + mq->offset;
1461           if (mq->ring->cookie != MEMIF_COOKIE)
1462             {
1463               DBG ("wrong cookie on rx ring %u", i);
1464               return MEMIF_ERR_COOKIE;
1465             }
1466           mq->ring->head = mq->ring->tail = mq->last_head = mq->next_buf = 0;
1467         }
1468     }
1469
1470   for (i = 0; i < c->tx_queues_num; i++)
1471     {
1472       mq = &c->tx_queues[i];
1473       if (mq != NULL)
1474         {
1475           mq->ring = c->regions[mq->region].addr + mq->offset;
1476           if (mq->ring->cookie != MEMIF_COOKIE)
1477             {
1478               DBG ("wrong cookie on tx ring %u", i);
1479               return MEMIF_ERR_COOKIE;
1480             }
1481           mq->ring->head = mq->ring->tail = mq->last_head = mq->next_buf = 0;
1482         }
1483     }
1484
1485   lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD,
1486                          lm->private_ctx);
1487
1488   return 0;
1489 }
1490
1491 static inline int
1492 memif_add_region (libmemif_main_t * lm, memif_connection_t * conn,
1493                   uint8_t has_buffers)
1494 {
1495   memif_region_t *r;
1496
1497   r =
1498     lm->realloc (conn->regions,
1499                  sizeof (memif_region_t) * ++conn->regions_num);
1500   if (r == NULL)
1501     return MEMIF_ERR_NOMEM;
1502
1503   conn->regions = r;
1504   r = &conn->regions[conn->regions_num - 1];
1505   memset (r, 0, sizeof (memif_region_t));
1506
1507   if (has_buffers != 0)
1508     {
1509       r->buffer_offset = 0;
1510     }
1511   else
1512     {
1513       r->buffer_offset =
1514         (conn->run_args.num_s2m_rings +
1515          conn->run_args.num_m2s_rings) * (sizeof (memif_ring_t) +
1516                                           sizeof (memif_desc_t) *
1517                                           (1 << conn->
1518                                            run_args.log2_ring_size));
1519     }
1520
1521   r->region_size = (has_buffers == 0) ? r->buffer_offset : r->buffer_offset +
1522     conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1523     (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1524
1525   if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1526     return memif_syscall_error_handler (errno);
1527
1528   if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
1529     return memif_syscall_error_handler (errno);
1530
1531   if ((ftruncate (r->fd, r->region_size)) == -1)
1532     return memif_syscall_error_handler (errno);
1533
1534   if ((r->addr = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
1535                        MAP_SHARED, r->fd, 0)) == MAP_FAILED)
1536     return memif_syscall_error_handler (errno);
1537
1538   return MEMIF_ERR_SUCCESS;
1539 }
1540
1541 static inline int
1542 memif_init_queues (libmemif_main_t * lm, memif_connection_t * conn)
1543 {
1544   int i, j;
1545   memif_ring_t *ring;
1546
1547   for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1548     {
1549       ring = memif_get_ring (conn, MEMIF_RING_S2M, i);
1550       DBG ("RING: %p I: %d", ring, i);
1551       ring->head = ring->tail = 0;
1552       ring->cookie = MEMIF_COOKIE;
1553       ring->flags = 0;
1554       for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1555         {
1556           uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1557           ring->desc[j].region = 1;
1558           ring->desc[j].offset =
1559             conn->regions[1].buffer_offset +
1560             (uint32_t) (slot * conn->run_args.buffer_size);
1561           ring->desc[j].length = conn->run_args.buffer_size;
1562         }
1563     }
1564   for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1565     {
1566       ring = memif_get_ring (conn, MEMIF_RING_M2S, i);
1567       DBG ("RING: %p I: %d", ring, i);
1568       ring->head = ring->tail = 0;
1569       ring->cookie = MEMIF_COOKIE;
1570       ring->flags = 0;
1571       for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1572         {
1573           uint16_t slot = (i + conn->run_args.num_s2m_rings) *
1574             (1 << conn->run_args.log2_ring_size) + j;
1575           ring->desc[j].region = 1;
1576           ring->desc[j].offset =
1577             conn->regions[1].buffer_offset +
1578             (uint32_t) (slot * conn->run_args.buffer_size);
1579           ring->desc[j].length = conn->run_args.buffer_size;
1580         }
1581     }
1582   memif_queue_t *mq;
1583   DBG ("alloc: %p", lm->alloc);
1584   DBG ("size: %lu", sizeof (memif_queue_t) * conn->run_args.num_s2m_rings);
1585   mq =
1586     (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
1587                                  conn->run_args.num_s2m_rings);
1588   if (mq == NULL)
1589     return MEMIF_ERR_NOMEM;
1590
1591   int x;
1592   memif_list_elt_t e;
1593   for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1594     {
1595       if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1596         return memif_syscall_error_handler (errno);
1597       e.key = mq[x].int_fd;
1598       e.data_struct = conn;
1599       add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
1600
1601       mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
1602       DBG ("RING: %p I: %d", mq[x].ring, x);
1603       mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1604       mq[x].region = 0;
1605       mq[x].offset =
1606         (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
1607       mq[x].last_head = mq[x].last_tail = 0;
1608       mq[x].next_buf = 0;
1609     }
1610   conn->tx_queues = mq;
1611   conn->tx_queues_num = conn->run_args.num_s2m_rings;
1612
1613   mq =
1614     (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
1615                                  conn->run_args.num_m2s_rings);
1616   if (mq == NULL)
1617     return MEMIF_ERR_NOMEM;
1618
1619   for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1620     {
1621       if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1622         return memif_syscall_error_handler (errno);
1623       e.key = mq[x].int_fd;
1624       e.data_struct = conn;
1625       add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
1626
1627       mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
1628       DBG ("RING: %p I: %d", mq[x].ring, x);
1629       mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1630       mq[x].region = 0;
1631       mq[x].offset =
1632         (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
1633       mq[x].last_head = mq[x].last_tail = 0;
1634       mq[x].next_buf = 0;
1635     }
1636   conn->rx_queues = mq;
1637   conn->rx_queues_num = conn->run_args.num_m2s_rings;
1638
1639   return MEMIF_ERR_SUCCESS;
1640 }
1641
1642 int
1643 memif_init_regions_and_queues (memif_connection_t * conn)
1644 {
1645   memif_region_t *r;
1646   libmemif_main_t *lm;
1647
1648   if (conn == NULL)
1649     return MEMIF_ERR_INVAL_ARG;
1650
1651   lm = get_libmemif_main (conn->args.socket);
1652
1653   /* region 0. rings */
1654   memif_add_region (lm, conn, /* has_buffers */ 0);
1655
1656   /* region 1. buffers */
1657   if (lm->add_external_region)
1658     {
1659       r =
1660         (memif_region_t *) lm->realloc (conn->regions,
1661                                         sizeof (memif_region_t) *
1662                                         ++conn->regions_num);
1663       if (r == NULL)
1664         return MEMIF_ERR_NOMEM;
1665       conn->regions = r;
1666
1667       conn->regions[1].region_size =
1668         conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1669         (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1670       conn->regions[1].buffer_offset = 0;
1671       lm->add_external_region (&conn->regions[1].addr,
1672                                conn->regions[1].region_size,
1673                                &conn->regions[1].fd, conn->private_ctx);
1674       conn->regions[1].is_external = 1;
1675     }
1676   else
1677     {
1678       memif_add_region (lm, conn, 1);
1679     }
1680
1681   memif_init_queues (lm, conn);
1682
1683   return 0;
1684 }
1685
1686 int
1687 memif_set_next_free_buffer (memif_conn_handle_t conn, uint16_t qid,
1688                             memif_buffer_t *buf)
1689 {
1690   memif_connection_t *c = (memif_connection_t *) conn;
1691   if (EXPECT_FALSE (c == NULL))
1692     return MEMIF_ERR_NOCONN;
1693   if (EXPECT_FALSE (qid >= c->tx_queues_num))
1694     return MEMIF_ERR_QID;
1695   if (EXPECT_FALSE (buf == NULL))
1696     return MEMIF_ERR_INVAL_ARG;
1697
1698   uint16_t ring_size, ns;
1699   memif_queue_t *mq = &c->tx_queues[qid];
1700   memif_ring_t *ring = mq->ring;
1701
1702   ring_size = (1 << mq->log2_ring_size);
1703   if (c->args.is_master)
1704     ns = ring->head - mq->next_buf;
1705   else
1706     ns = ring_size - mq->next_buf + ring->tail;
1707
1708   if ((mq->next_buf - buf->desc_index) > ns)
1709     return MEMIF_ERR_INVAL_ARG;
1710
1711   mq->next_buf = buf->desc_index;
1712
1713   return MEMIF_ERR_SUCCESS;
1714 }
1715
1716 static void
1717 memif_buffer_enq_at_idx_internal (memif_queue_t *from_q, memif_queue_t *to_q,
1718                                   memif_buffer_t *buf, uint16_t slot)
1719 {
1720   uint16_t from_mask = (1 << from_q->log2_ring_size) - 1;
1721   uint16_t to_mask = (1 << to_q->log2_ring_size) - 1;
1722   memif_desc_t *from_d, *to_d, tmp_d;
1723
1724   /* Get the descriptors */
1725   from_d = &from_q->ring->desc[buf->desc_index & from_mask];
1726   to_d = &to_q->ring->desc[slot & to_mask];
1727
1728   /* Swap descriptors */
1729   tmp_d = *from_d;
1730   *from_d = *to_d;
1731   *to_d = tmp_d;
1732
1733   /* Update descriptor index and queue for clients buffer */
1734   buf->desc_index = slot;
1735   buf->queue = to_q;
1736 }
1737
1738 int
1739 memif_buffer_requeue (memif_conn_handle_t conn, memif_buffer_t *buf_a,
1740                       memif_buffer_t *buf_b)
1741 {
1742   memif_connection_t *c = (memif_connection_t *) conn;
1743   if (EXPECT_FALSE (c == NULL))
1744     return MEMIF_ERR_NOCONN;
1745   if (EXPECT_FALSE (c->args.is_master))
1746     return MEMIF_ERR_INVAL_ARG;
1747   if ((buf_a == NULL) || (buf_b == NULL))
1748     return MEMIF_ERR_INVAL_ARG;
1749
1750   int err;
1751   /* store buf_a information */
1752   uint16_t index_a = buf_a->desc_index;
1753   memif_queue_t *mq_a = buf_a->queue;
1754
1755   /* swap buffers, buf_a was updated with new desc_index and queue */
1756   memif_buffer_enq_at_idx_internal ((memif_queue_t *) buf_a->queue,
1757                                     (memif_queue_t *) buf_b->queue, buf_a,
1758                                     buf_b->desc_index);
1759
1760   /* update buf_b desc_index and queue */
1761   buf_b->desc_index = index_a;
1762   buf_b->queue = mq_a;
1763
1764   return MEMIF_ERR_SUCCESS;
1765 }
1766
1767 int
1768 memif_buffer_enq_tx (memif_conn_handle_t conn, uint16_t qid,
1769                      memif_buffer_t * bufs, uint16_t count,
1770                      uint16_t * count_out)
1771 {
1772   memif_connection_t *c = (memif_connection_t *) conn;
1773   if (EXPECT_FALSE (c == NULL))
1774     return MEMIF_ERR_NOCONN;
1775   if (EXPECT_FALSE (c->fd < 0))
1776     return MEMIF_ERR_DISCONNECTED;
1777   if (EXPECT_FALSE (qid >= c->tx_queues_num))
1778     return MEMIF_ERR_QID;
1779   if (EXPECT_FALSE (!count_out))
1780     return MEMIF_ERR_INVAL_ARG;
1781   if (EXPECT_FALSE (c->args.is_master))
1782     return MEMIF_ERR_INVAL_ARG;
1783
1784   memif_queue_t *mq = &c->tx_queues[qid];
1785   memif_ring_t *ring = mq->ring;
1786   memif_buffer_t *b0;
1787   uint16_t mask = (1 << mq->log2_ring_size) - 1;
1788   uint16_t ring_size;
1789   uint16_t ns;
1790   memif_queue_t *bmq;
1791   int err = MEMIF_ERR_SUCCESS;  /* 0 */
1792   *count_out = 0;
1793
1794   ring_size = (1 << mq->log2_ring_size);
1795
1796   /* can only be called by slave */
1797   ns = ring_size - mq->next_buf + ring->tail;
1798
1799   b0 = bufs;
1800
1801   while (count && ns)
1802     {
1803       /* Swaps the descriptors, updates next_buf pointer and updates client
1804        * memif buffer */
1805
1806       memif_buffer_enq_at_idx_internal ((memif_queue_t *) b0->queue, mq, b0,
1807                                         mq->next_buf);
1808
1809       mq->next_buf++; /* mark the buffer as allocated */
1810       count--;
1811       ns--;
1812       b0++;
1813       *count_out += 1;
1814     }
1815
1816   DBG ("allocated: %u/%u bufs. Next buffer pointer %d", *count_out, count,
1817        mq->next_buf);
1818
1819   if (count)
1820     {
1821       DBG ("ring buffer full! qid: %u", qid);
1822       err = MEMIF_ERR_NOBUF_RING;
1823     }
1824
1825   return err;
1826 }
1827
1828 int
1829 memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
1830                     memif_buffer_t * bufs, uint16_t count,
1831                     uint16_t * count_out, uint16_t size)
1832 {
1833   memif_connection_t *c = (memif_connection_t *) conn;
1834   if (EXPECT_FALSE (c == NULL))
1835     return MEMIF_ERR_NOCONN;
1836   if (EXPECT_FALSE (c->fd < 0))
1837     return MEMIF_ERR_DISCONNECTED;
1838   uint8_t num =
1839     (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1840     run_args.num_s2m_rings;
1841   if (EXPECT_FALSE (qid >= num))
1842     return MEMIF_ERR_QID;
1843   if (EXPECT_FALSE (!count_out))
1844     return MEMIF_ERR_INVAL_ARG;
1845
1846   libmemif_main_t *lm = get_libmemif_main (c->args.socket);
1847   memif_queue_t *mq = &c->tx_queues[qid];
1848   memif_ring_t *ring = mq->ring;
1849   memif_buffer_t *b0;
1850   uint16_t mask = (1 << mq->log2_ring_size) - 1;
1851   uint32_t offset_mask = c->run_args.buffer_size - 1;
1852   uint16_t ring_size;
1853   uint16_t ns;
1854   int err = MEMIF_ERR_SUCCESS;  /* 0 */
1855   uint16_t dst_left, src_left;
1856   uint16_t saved_count;
1857   uint16_t saved_next_buf;
1858   memif_buffer_t *saved_b;
1859   *count_out = 0;
1860
1861   ring_size = (1 << mq->log2_ring_size);
1862
1863   if (c->args.is_master)
1864     ns = ring->head - mq->next_buf;
1865   else
1866     ns = ring_size - mq->next_buf + ring->tail;
1867
1868   while (count && ns)
1869     {
1870       b0 = (bufs + *count_out);
1871
1872       saved_b = b0;
1873       saved_count = count;
1874       saved_next_buf = mq->next_buf;
1875
1876       b0->desc_index = mq->next_buf;
1877       ring->desc[mq->next_buf & mask].flags = 0;
1878
1879       /* slave can produce buffer with original length */
1880       dst_left = (c->args.is_master) ? ring->desc[mq->next_buf & mask].length :
1881                                        c->run_args.buffer_size;
1882       src_left = size;
1883
1884       while (src_left)
1885         {
1886           if (EXPECT_FALSE (dst_left == 0))
1887             {
1888               if (count && ns)
1889                 {
1890                   *count_out += 1;
1891                   mq->next_buf++;
1892                   ns--;
1893
1894                   ring->desc[b0->desc_index & mask].flags |=
1895                     MEMIF_DESC_FLAG_NEXT;
1896                   b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
1897
1898                   b0 = (bufs + *count_out);
1899                   b0->desc_index = mq->next_buf;
1900                   dst_left = (c->args.is_master) ?
1901                                ring->desc[mq->next_buf & mask].length :
1902                                c->run_args.buffer_size;
1903                   ring->desc[mq->next_buf & mask].flags = 0;
1904                 }
1905               else
1906                 {
1907                   /* rollback allocated chain buffers */
1908                   memset (saved_b, 0, sizeof (memif_buffer_t)
1909                           * (saved_count - count + 1));
1910                   *count_out -= saved_count - count;
1911                   mq->next_buf = saved_next_buf;
1912                   goto no_ns;
1913                 }
1914             }
1915           b0->len = memif_min (dst_left, src_left);
1916
1917           /* slave resets buffer offset */
1918           if (c->args.is_master == 0)
1919             {
1920               memif_desc_t *d = &ring->desc[mq->next_buf & mask];
1921               if (lm->get_external_buffer_offset)
1922                 d->offset = lm->get_external_buffer_offset (c->private_ctx);
1923               else
1924                 d->offset = d->offset - (d->offset & offset_mask);
1925             }
1926           b0->data = memif_get_buffer (c, ring, mq->next_buf & mask);
1927
1928           src_left -= b0->len;
1929           dst_left -= b0->len;
1930         }
1931
1932       *count_out += 1;
1933       mq->next_buf++;
1934       ns--;
1935       count--;
1936     }
1937
1938 no_ns:
1939
1940   DBG ("allocated: %u/%u bufs. Next buffer pointer %d", *count_out, count,
1941        mq->next_buf);
1942
1943   if (count)
1944     {
1945       DBG ("ring buffer full! qid: %u", qid);
1946       err = MEMIF_ERR_NOBUF_RING;
1947     }
1948
1949   return err;
1950 }
1951
1952 int
1953 memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count,
1954                     uint16_t headroom)
1955 {
1956   memif_connection_t *c = (memif_connection_t *) conn;
1957   if (EXPECT_FALSE (c == NULL))
1958     return MEMIF_ERR_NOCONN;
1959   if (EXPECT_FALSE (c->fd < 0))
1960     return MEMIF_ERR_DISCONNECTED;
1961   uint8_t num =
1962     (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1963     run_args.num_m2s_rings;
1964   if (EXPECT_FALSE (qid >= num))
1965     return MEMIF_ERR_QID;
1966   libmemif_main_t *lm = get_libmemif_main (c->args.socket);
1967   memif_queue_t *mq = &c->rx_queues[qid];
1968   memif_ring_t *ring = mq->ring;
1969   uint16_t mask = (1 << mq->log2_ring_size) - 1;
1970   uint32_t offset_mask = c->run_args.buffer_size - 1;
1971   uint16_t slot, counter = 0;
1972
1973   if (c->args.is_master)
1974     {
1975       MEMIF_MEMORY_BARRIER ();
1976       ring->tail =
1977         (ring->tail + count <=
1978          mq->last_head) ? ring->tail + count : mq->last_head;
1979       return MEMIF_ERR_SUCCESS;
1980     }
1981
1982   uint16_t head = ring->head;
1983   slot = head;
1984   uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
1985   count = (count < ns) ? count : ns;
1986
1987   memif_desc_t *d;
1988   while (counter < count)
1989     {
1990       d = &ring->desc[slot & mask];
1991       d->region = 1;
1992       d->length = c->run_args.buffer_size - headroom;
1993       if (lm->get_external_buffer_offset)
1994         d->offset = lm->get_external_buffer_offset (c->private_ctx);
1995       else
1996         d->offset = d->offset - (d->offset & offset_mask) + headroom;
1997       slot++;
1998       counter++;
1999     }
2000
2001   MEMIF_MEMORY_BARRIER ();
2002   ring->head = slot;
2003
2004   return MEMIF_ERR_SUCCESS;     /* 0 */
2005 }
2006
2007 int
2008 memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
2009                 memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
2010 {
2011   memif_connection_t *c = (memif_connection_t *) conn;
2012   if (EXPECT_FALSE (c == NULL))
2013     return MEMIF_ERR_NOCONN;
2014   if (EXPECT_FALSE (c->fd < 0))
2015     return MEMIF_ERR_DISCONNECTED;
2016   uint8_t num =
2017     (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2018     run_args.num_s2m_rings;
2019   if (EXPECT_FALSE (qid >= num))
2020     return MEMIF_ERR_QID;
2021   if (EXPECT_FALSE (!tx))
2022     return MEMIF_ERR_INVAL_ARG;
2023
2024   memif_queue_t *mq = &c->tx_queues[qid];
2025   memif_ring_t *ring = mq->ring;
2026   uint16_t mask = (1 << mq->log2_ring_size) - 1;
2027   uint32_t offset_mask = c->run_args.buffer_size - 1;
2028   memif_buffer_t *b0;
2029   memif_desc_t *d;
2030   int64_t data_offset;
2031   *tx = 0;
2032   int err = MEMIF_ERR_SUCCESS;
2033
2034   if (EXPECT_FALSE (count == 0))
2035     return MEMIF_ERR_SUCCESS;
2036
2037   uint16_t index;
2038   if (c->args.is_master)
2039     index = ring->tail;
2040   else
2041     index = ring->head;
2042
2043   while (count)
2044     {
2045       b0 = (bufs + *tx);
2046       /* set error to MEMIF_ERR_INVAL_ARG and finish the sending process
2047        */
2048       if ((b0->desc_index & mask) != (index & mask))
2049         {
2050           err = MEMIF_ERR_INVAL_ARG;
2051           goto done;
2052         }
2053       d = &ring->desc[b0->desc_index & mask];
2054       d->length = b0->len;
2055       if (!c->args.is_master)
2056         {
2057           // reset headroom
2058           d->offset = d->offset - (d->offset & offset_mask);
2059           // calculate offset from user data
2060           data_offset = b0->data - (d->offset + c->regions[d->region].addr);
2061           if (data_offset != 0)
2062             {
2063               /* verify data offset and buffer length */
2064               if ((data_offset < 0) ||
2065                   ((data_offset + b0->len) > c->run_args.buffer_size))
2066                 {
2067                   DBG ("slot: %d, data_offset: %d, length: %d",
2068                        b0->desc_index & mask, data_offset, b0->len);
2069                   err = MEMIF_ERR_INVAL_ARG;
2070                   goto done;
2071                 }
2072               d->offset += data_offset;
2073             }
2074         }
2075
2076 #ifdef MEMIF_DBG_SHM
2077       printf ("offset: %-6d\n", ring->desc[b0->desc_index & mask].offset);
2078       printf ("data: %p\n",
2079               memif_get_buffer (c, ring, b0->desc_index & mask));
2080       printf ("index: %u\n", b0->desc_index);
2081       print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
2082                    ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
2083 #endif /* MEMIF_DBG_SHM */
2084
2085       *tx += 1;
2086       count--;
2087       index++;
2088     }
2089
2090 done:
2091   MEMIF_MEMORY_BARRIER ();
2092   if (c->args.is_master)
2093     ring->tail = b0->desc_index + 1;
2094   else
2095     ring->head = b0->desc_index + 1;
2096
2097   if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
2098     {
2099       uint64_t a = 1;
2100       int r = write (mq->int_fd, &a, sizeof (a));
2101       if (r < 0)
2102         return MEMIF_ERR_INT_WRITE;
2103     }
2104
2105   return err;
2106 }
2107
2108 int
2109 memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
2110                 memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
2111 {
2112   memif_connection_t *c = (memif_connection_t *) conn;
2113   if (EXPECT_FALSE (c == NULL))
2114     return MEMIF_ERR_NOCONN;
2115   if (EXPECT_FALSE (c->fd < 0))
2116     return MEMIF_ERR_DISCONNECTED;
2117   uint8_t num =
2118     (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2119     run_args.num_m2s_rings;
2120   if (EXPECT_FALSE (qid >= num))
2121     return MEMIF_ERR_QID;
2122   if (EXPECT_FALSE (!rx))
2123     return MEMIF_ERR_INVAL_ARG;
2124
2125   memif_queue_t *mq = &c->rx_queues[qid];
2126   memif_ring_t *ring = mq->ring;
2127   uint16_t cur_slot, last_slot;
2128   uint16_t ns;
2129   uint16_t mask = (1 << mq->log2_ring_size) - 1;
2130   memif_buffer_t *b0;
2131   *rx = 0;
2132
2133   uint64_t b;
2134   ssize_t r;
2135
2136   cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
2137   last_slot = (c->args.is_master) ? ring->head : ring->tail;
2138   if (cur_slot == last_slot)
2139     {
2140       r = read (mq->int_fd, &b, sizeof (b));
2141       if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
2142                         return memif_syscall_error_handler (errno);
2143
2144       return MEMIF_ERR_SUCCESS;
2145     }
2146
2147   ns = last_slot - cur_slot;
2148
2149   while (ns && count)
2150     {
2151       b0 = (bufs + *rx);
2152
2153       b0->desc_index = cur_slot;
2154       b0->data = memif_get_buffer (c, ring, cur_slot & mask);
2155       b0->len = ring->desc[cur_slot & mask].length;
2156       /* slave resets buffer length */
2157       if (c->args.is_master == 0)
2158         {
2159           ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
2160         }
2161
2162       if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
2163         {
2164           b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
2165           ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
2166         }
2167
2168       b0->queue = mq;
2169 #ifdef MEMIF_DBG_SHM
2170       printf ("data: %p\n", b0->data);
2171       printf ("index: %u\n", b0->desc_index);
2172       printf ("queue: %p\n", b0->queue);
2173       print_bytes (b0->data, b0->len, DBG_RX_BUF);
2174 #endif /* MEMIF_DBG_SHM */
2175       ns--;
2176       *rx += 1;
2177
2178       count--;
2179       cur_slot++;
2180     }
2181
2182   if (c->args.is_master)
2183     mq->last_head = cur_slot;
2184   else
2185     mq->last_tail = cur_slot;
2186
2187   if (ns)
2188     {
2189       DBG ("not enough buffers!");
2190       return MEMIF_ERR_NOBUF;
2191     }
2192
2193   r = read (mq->int_fd, &b, sizeof (b));
2194   if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
2195     return memif_syscall_error_handler (errno);
2196
2197   return MEMIF_ERR_SUCCESS;     /* 0 */
2198 }
2199
2200 int
2201 memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
2202                    char *buf, ssize_t buflen)
2203 {
2204   memif_connection_t *c = (memif_connection_t *) conn;
2205   libmemif_main_t *lm;
2206   memif_socket_t *ms;
2207   int err = MEMIF_ERR_SUCCESS, i;
2208   ssize_t l0 = 0, l1;
2209
2210   if (c == NULL)
2211     return MEMIF_ERR_NOCONN;
2212
2213   ms = (memif_socket_t *) c->args.socket;
2214   lm = get_libmemif_main (ms);
2215
2216   l1 = strlen ((char *) c->args.interface_name);
2217   if (l0 + l1 < buflen)
2218     {
2219       md->if_name =
2220         (uint8_t *) strcpy (buf + l0, (char *) c->args.interface_name);
2221       l0 += l1 + 1;
2222     }
2223   else
2224     err = MEMIF_ERR_NOBUF_DET;
2225
2226   l1 = strlen ((char *) lm->app_name);
2227   if (l0 + l1 < buflen)
2228     {
2229       md->inst_name = (uint8_t *) strcpy (buf + l0, (char *) lm->app_name);
2230       l0 += l1 + 1;
2231     }
2232   else
2233     err = MEMIF_ERR_NOBUF_DET;
2234
2235   l1 = strlen ((char *) c->remote_if_name);
2236   if (l0 + l1 < buflen)
2237     {
2238       md->remote_if_name =
2239         (uint8_t *) strcpy (buf + l0, (char *) c->remote_if_name);
2240       l0 += l1 + 1;
2241     }
2242   else
2243     err = MEMIF_ERR_NOBUF_DET;
2244
2245   l1 = strlen ((char *) c->remote_name);
2246   if (l0 + l1 < buflen)
2247     {
2248       md->remote_inst_name =
2249         (uint8_t *) strcpy (buf + l0, (char *) c->remote_name);
2250       l0 += l1 + 1;
2251     }
2252   else
2253     err = MEMIF_ERR_NOBUF_DET;
2254
2255   md->id = c->args.interface_id;
2256
2257   if (strlen ((char *) c->args.secret) > 0)
2258     {
2259       l1 = strlen ((char *) c->args.secret);
2260       if (l0 + l1 < buflen)
2261         {
2262           md->secret = (uint8_t *) strcpy (buf + l0, (char *) c->args.secret);
2263           l0 += l1 + 1;
2264         }
2265       else
2266         err = MEMIF_ERR_NOBUF_DET;
2267     }
2268
2269   md->role = (c->args.is_master) ? 0 : 1;
2270   md->mode = c->args.mode;
2271
2272   l1 = strlen ((char *) ms->filename);
2273   if (l0 + l1 < buflen)
2274     {
2275       md->socket_filename =
2276         (uint8_t *) strcpy (buf + l0, (char *) ms->filename);
2277       l0 += l1 + 1;
2278     }
2279   else
2280     err = MEMIF_ERR_NOBUF_DET;
2281
2282   l1 = strlen ((char *) c->remote_disconnect_string);
2283   if (l0 + l1 < buflen)
2284     {
2285       md->error =
2286         (uint8_t *) strcpy (buf + l0, (char *) c->remote_disconnect_string);
2287       l0 += l1 + 1;
2288     }
2289   else
2290     err = MEMIF_ERR_NOBUF_DET;
2291
2292   md->regions_num = c->regions_num;
2293   l1 = sizeof (memif_region_details_t) * md->regions_num;
2294   if (l0 + l1 <= buflen)
2295     {
2296       md->regions = (memif_region_details_t *) (buf + l0);
2297       for (i = 0; i < md->regions_num; i++)
2298         {
2299           md->regions[i].index = i;
2300           md->regions[i].addr = c->regions[i].addr;
2301           md->regions[i].size = c->regions[i].region_size;
2302           md->regions[i].fd = c->regions[i].fd;
2303           md->regions[i].is_external = c->regions[i].is_external;
2304         }
2305       l0 += l1;
2306     }
2307   else
2308     err = MEMIF_ERR_NOBUF_DET;
2309
2310   md->rx_queues_num =
2311     (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2312     run_args.num_m2s_rings;
2313
2314   l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
2315   if (l0 + l1 <= buflen)
2316     {
2317       md->rx_queues = (memif_queue_details_t *) (buf + l0);
2318       for (i = 0; i < md->rx_queues_num; i++)
2319         {
2320           md->rx_queues[i].region = c->rx_queues[i].region;
2321           md->rx_queues[i].qid = i;
2322           md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
2323           md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
2324           md->rx_queues[i].head = c->rx_queues[i].ring->head;
2325           md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
2326           md->rx_queues[i].buffer_size = c->run_args.buffer_size;
2327         }
2328       l0 += l1;
2329     }
2330   else
2331     err = MEMIF_ERR_NOBUF_DET;
2332
2333   md->tx_queues_num =
2334     (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2335     run_args.num_s2m_rings;
2336
2337   l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
2338   if (l0 + l1 <= buflen)
2339     {
2340       md->tx_queues = (memif_queue_details_t *) (buf + l0);
2341       for (i = 0; i < md->tx_queues_num; i++)
2342         {
2343           md->tx_queues[i].region = c->tx_queues[i].region;
2344           md->tx_queues[i].qid = i;
2345           md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
2346           md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
2347           md->tx_queues[i].head = c->tx_queues[i].ring->head;
2348           md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
2349           md->tx_queues[i].buffer_size = c->run_args.buffer_size;
2350         }
2351       l0 += l1;
2352     }
2353   else
2354     err = MEMIF_ERR_NOBUF_DET;
2355
2356   md->link_up_down = (c->fd > 0) ? 1 : 0;
2357
2358   return err;                   /* 0 */
2359 }
2360
2361 int
2362 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
2363 {
2364   memif_connection_t *c = (memif_connection_t *) conn;
2365   uint8_t num;
2366
2367   *efd = -1;
2368   if (c == NULL)
2369     return MEMIF_ERR_NOCONN;
2370   if (c->fd < 0)
2371     return MEMIF_ERR_DISCONNECTED;
2372
2373   num =
2374     (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2375     run_args.num_m2s_rings;
2376   if (qid >= num)
2377     return MEMIF_ERR_QID;
2378
2379   *efd = c->rx_queues[qid].int_fd;
2380
2381   return MEMIF_ERR_SUCCESS;
2382 }
2383
2384 int
2385 memif_cleanup ()
2386 {
2387   libmemif_main_t *lm = &libmemif_main;
2388   int err;
2389
2390   err = memif_delete_socket ((memif_socket_handle_t *) & lm->default_socket);
2391   if (err != MEMIF_ERR_SUCCESS)
2392     return err;
2393
2394   if (lm->control_list)
2395     lm->free (lm->control_list);
2396   lm->control_list = NULL;
2397   if (lm->interrupt_list)
2398     lm->free (lm->interrupt_list);
2399   lm->interrupt_list = NULL;
2400   if (lm->socket_list)
2401     lm->free (lm->socket_list);
2402   lm->socket_list = NULL;
2403   if (lm->pending_list)
2404     lm->free (lm->pending_list);
2405   lm->pending_list = NULL;
2406   if (lm->poll_cancel_fd != -1)
2407     close (lm->poll_cancel_fd);
2408
2409   return MEMIF_ERR_SUCCESS;     /* 0 */
2410 }