libmemif: Add memif_cancel_poll_event() + bug fixing.
[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 37
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 };
147
148 #define MEMIF_ERR_UNDEFINED "undefined error"
149
150 char *
151 memif_strerror (int err_code)
152 {
153   if (err_code >= ERRLIST_LEN)
154     {
155       strncpy (memif_buf, MEMIF_ERR_UNDEFINED, strlen (MEMIF_ERR_UNDEFINED));
156       memif_buf[strlen (MEMIF_ERR_UNDEFINED)] = '\0';
157     }
158   else
159     {
160       strncpy (memif_buf, memif_errlist[err_code],
161                strlen (memif_errlist[err_code]));
162       memif_buf[strlen (memif_errlist[err_code])] = '\0';
163     }
164   return memif_buf;
165 }
166
167 #define DBG_TX_BUF (0)
168 #define DBG_RX_BUF (1)
169
170 #ifdef MEMIF_DBG_SHM
171 static void
172 print_bytes (void *data, uint16_t len, uint8_t q)
173 {
174   if (q == DBG_TX_BUF)
175     printf ("\nTX:\n\t");
176   else
177     printf ("\nRX:\n\t");
178   int i;
179   for (i = 0; i < len; i++)
180     {
181       if (i % 8 == 0)
182         printf ("\n%d:\t", i);
183       printf ("%02X ", ((uint8_t *) (data))[i]);
184     }
185   printf ("\n\n");
186 }
187 #endif /* MEMIF_DBG_SHM */
188
189 int
190 memif_syscall_error_handler (int err_code)
191 {
192   DBG_UNIX ("%s", strerror (err_code));
193
194   if (err_code == 0)
195     return MEMIF_ERR_SUCCESS;
196   if (err_code == EACCES)
197     return MEMIF_ERR_ACCES;
198   if (err_code == ENFILE)
199     return MEMIF_ERR_FILE_LIMIT;
200   if (err_code == EMFILE)
201     return MEMIF_ERR_PROC_FILE_LIMIT;
202   if (err_code == ENOMEM)
203     return MEMIF_ERR_NOMEM;
204 /* connection refused if master dows not exist
205     this error would spam the user until master was created */
206   if (err_code == ECONNREFUSED)
207     return MEMIF_ERR_SUCCESS;
208   if (err_code == EALREADY)
209     return MEMIF_ERR_ALREADY;
210   if (err_code == EAGAIN)
211     return MEMIF_ERR_AGAIN;
212   if (err_code == EBADF)
213     return MEMIF_ERR_BAD_FD;
214   if (err_code == ENOENT)
215     return MEMIF_ERR_NO_FILE;
216
217   /* other syscall errors */
218   return MEMIF_ERR_SYSCALL;
219 }
220
221 static int
222 memif_add_epoll_fd (int fd, uint32_t events)
223 {
224   if (fd < 0)
225     {
226       DBG ("invalid fd %d", fd);
227       return -1;
228     }
229   struct epoll_event evt;
230   memset (&evt, 0, sizeof (evt));
231   evt.events = events;
232   evt.data.fd = fd;
233   if (epoll_ctl (memif_epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
234     {
235       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
236       return -1;
237     }
238   DBG ("fd %d added to epoll", fd);
239   return 0;
240 }
241
242 static int
243 memif_mod_epoll_fd (int fd, uint32_t events)
244 {
245   if (fd < 0)
246     {
247       DBG ("invalid fd %d", fd);
248       return -1;
249     }
250   struct epoll_event evt;
251   memset (&evt, 0, sizeof (evt));
252   evt.events = events;
253   evt.data.fd = fd;
254   if (epoll_ctl (memif_epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
255     {
256       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
257       return -1;
258     }
259   DBG ("fd %d moddified on epoll", fd);
260   return 0;
261 }
262
263 static int
264 memif_del_epoll_fd (int fd)
265 {
266   if (fd < 0)
267     {
268       DBG ("invalid fd %d", fd);
269       return -1;
270     }
271   struct epoll_event evt;
272   memset (&evt, 0, sizeof (evt));
273   if (epoll_ctl (memif_epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
274     {
275       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
276       return -1;
277     }
278   DBG ("fd %d removed from epoll", fd);
279   return 0;
280 }
281
282 int
283 memif_control_fd_update (int fd, uint8_t events)
284 {
285   if (events & MEMIF_FD_EVENT_DEL)
286     return memif_del_epoll_fd (fd);
287
288   uint32_t evt = 0;
289   if (events & MEMIF_FD_EVENT_READ)
290     evt |= EPOLLIN;
291   if (events & MEMIF_FD_EVENT_WRITE)
292     evt |= EPOLLOUT;
293
294   if (events & MEMIF_FD_EVENT_MOD)
295     return memif_mod_epoll_fd (fd, evt);
296
297   return memif_add_epoll_fd (fd, evt);
298 }
299
300 int
301 add_list_elt (memif_list_elt_t * e, memif_list_elt_t ** list, uint16_t * len)
302 {
303   libmemif_main_t *lm = &libmemif_main;
304
305   int i;
306   for (i = 0; i < *len; i++)
307     {
308       if ((*list)[i].data_struct == NULL)
309         {
310           (*list)[i].key = e->key;
311           (*list)[i].data_struct = e->data_struct;
312           return i;
313         }
314     }
315   memif_list_elt_t *tmp;
316   tmp = realloc (*list, sizeof (memif_list_elt_t) * *len * 2);
317   if (tmp == NULL)
318     return -1;
319
320   for (i = *len; i < *len * 2; i++)
321     {
322       tmp[i].key = -1;
323       tmp[i].data_struct = NULL;
324     }
325
326   tmp[*len].key = e->key;
327   tmp[*len].data_struct = e->data_struct;
328   i = *len;
329   *len = *len * 2;
330   *list = tmp;
331
332   return i;
333 }
334
335 int
336 get_list_elt (memif_list_elt_t ** e, memif_list_elt_t * list, uint16_t len,
337               int key)
338 {
339   if (key == -1)
340     {
341       *e = NULL;
342       return -1;
343     }
344   int i;
345   for (i = 0; i < len; i++)
346     {
347       if (list[i].key == key)
348         {
349           *e = &list[i];
350           return 0;
351         }
352     }
353   *e = NULL;
354   return -1;
355 }
356
357 /* does not free memory, only marks element as free */
358 int
359 free_list_elt (memif_list_elt_t * list, uint16_t len, int key)
360 {
361   int i;
362   for (i = 0; i < len; i++)
363     {
364       if (list[i].key == key)
365         {
366           list[i].key = -1;
367           list[i].data_struct = NULL;
368           return 0;
369         }
370     }
371
372   return -1;
373 }
374
375 int
376 free_list_elt_ctx (memif_list_elt_t * list, uint16_t len,
377                    memif_connection_t * ctx)
378 {
379   int i;
380   for (i = 0; i < len; i++)
381     {
382       if (list[i].key == -1)
383         {
384           if (list[i].data_struct == ctx)
385             {
386               list[i].data_struct = NULL;
387               return 0;
388             }
389         }
390     }
391
392   return -1;
393 }
394
395 static void
396 memif_control_fd_update_register (memif_control_fd_update_t * cb)
397 {
398   libmemif_main_t *lm = &libmemif_main;
399   lm->control_fd_update = cb;
400 }
401
402 int
403 memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name)
404 {
405   int err = MEMIF_ERR_SUCCESS;  /* 0 */
406   libmemif_main_t *lm = &libmemif_main;
407
408   if (app_name)
409     {
410       lm->app_name = malloc (strlen (app_name) + sizeof (char));
411       memset (lm->app_name, 0, strlen (app_name) + sizeof (char));
412       strncpy ((char *) lm->app_name, app_name, strlen (app_name));
413     }
414   else
415     {
416       lm->app_name = malloc (strlen (MEMIF_DEFAULT_APP_NAME) + sizeof (char));
417       memset (lm->app_name, 0, strlen (app_name) + sizeof (char));
418       strncpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
419                strlen (MEMIF_DEFAULT_APP_NAME));
420     }
421
422   /* register control fd update callback */
423   if (on_control_fd_update != NULL)
424     memif_control_fd_update_register (on_control_fd_update);
425   else
426     {
427       memif_epfd = epoll_create (1);
428       memif_control_fd_update_register (memif_control_fd_update);
429       if ((poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
430         {
431           err = errno;
432           DBG ("eventfd: %s", strerror (err));
433           return memif_syscall_error_handler (err);
434         }
435       lm->control_fd_update (poll_cancel_fd, MEMIF_FD_EVENT_READ);
436       DBG ("libmemif event polling initialized");
437     }
438
439   memset (&lm->ms, 0, sizeof (memif_socket_t));
440
441   lm->control_list_len = 2;
442   lm->interrupt_list_len = 2;
443   lm->listener_list_len = 1;
444   lm->pending_list_len = 1;
445
446   lm->control_list =
447     malloc (sizeof (memif_list_elt_t) * lm->control_list_len);
448   lm->interrupt_list =
449     malloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
450   lm->listener_list =
451     malloc (sizeof (memif_list_elt_t) * lm->listener_list_len);
452   lm->pending_list =
453     malloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
454
455   int i;
456   for (i = 0; i < lm->control_list_len; i++)
457     {
458       lm->control_list[i].key = -1;
459       lm->control_list[i].data_struct = NULL;
460     }
461   for (i = 0; i < lm->interrupt_list_len; i++)
462     {
463       lm->interrupt_list[i].key = -1;
464       lm->interrupt_list[i].data_struct = NULL;
465     }
466   for (i = 0; i < lm->listener_list_len; i++)
467     {
468       lm->listener_list[i].key = -1;
469       lm->listener_list[i].data_struct = NULL;
470     }
471   for (i = 0; i < lm->pending_list_len; i++)
472     {
473       lm->pending_list[i].key = -1;
474       lm->pending_list[i].data_struct = NULL;
475     }
476
477   lm->disconn_slaves = 0;
478
479   lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
480   if (lm->timerfd < 0)
481     {
482       err = errno;
483       DBG ("timerfd: %s", strerror (err));
484       return memif_syscall_error_handler (err);
485     }
486
487   lm->arm.it_value.tv_sec = 2;
488   lm->arm.it_value.tv_nsec = 0;
489   lm->arm.it_interval.tv_sec = 2;
490   lm->arm.it_interval.tv_nsec = 0;
491   memset (&lm->disarm, 0, sizeof (lm->disarm));
492
493   if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ) < 0)
494     {
495       DBG ("callback type memif_control_fd_update_t error!");
496       return MEMIF_ERR_CB_FDUPDATE;
497     }
498
499   return 0;
500 }
501
502 static inline memif_ring_t *
503 memif_get_ring (memif_connection_t * conn, memif_ring_type_t type,
504                 uint16_t ring_num)
505 {
506   if (&conn->regions[0] == NULL)
507     return NULL;
508   void *p = conn->regions[0].shm;
509   int ring_size =
510     sizeof (memif_ring_t) +
511     sizeof (memif_desc_t) * (1 << conn->run_args.log2_ring_size);
512   p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
513
514   return (memif_ring_t *) p;
515 }
516
517 int
518 memif_set_rx_mode (memif_conn_handle_t c, memif_rx_mode_t rx_mode,
519                    uint16_t qid)
520 {
521   memif_connection_t *conn = (memif_connection_t *) c;
522   if (conn == NULL)
523     return MEMIF_ERR_NOCONN;
524   uint8_t num =
525     (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->run_args.
526     num_m2s_rings;
527   if (qid >= num)
528     return MEMIF_ERR_QID;
529
530   conn->rx_queues[qid].ring->flags = rx_mode;
531   DBG ("rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
532   return MEMIF_ERR_SUCCESS;
533 }
534
535 int
536 memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
537               memif_connection_update_t * on_connect,
538               memif_connection_update_t * on_disconnect,
539               memif_interrupt_t * on_interrupt, void *private_ctx)
540 {
541   int err, i, index, sockfd = -1;
542   memif_list_elt_t list_elt;
543   memif_connection_t *conn = (memif_connection_t *) * c;
544   if (conn != NULL)
545     {
546       DBG ("This handle already points to existing memif.");
547       return MEMIF_ERR_CONN;
548     }
549   conn = (memif_connection_t *) malloc (sizeof (memif_connection_t));
550   if (conn == NULL)
551     {
552       err = memif_syscall_error_handler (errno);
553       goto error;
554     }
555   memset (conn, 0, sizeof (memif_connection_t));
556
557   libmemif_main_t *lm = &libmemif_main;
558
559   conn->args.interface_id = args->interface_id;
560
561   if (args->log2_ring_size == 0)
562     args->log2_ring_size = MEMIF_DEFAULT_LOG2_RING_SIZE;
563   if (args->buffer_size == 0)
564     args->buffer_size = MEMIF_DEFAULT_BUFFER_SIZE;
565   if (args->num_s2m_rings == 0)
566     args->num_s2m_rings = MEMIF_DEFAULT_TX_QUEUES;
567   if (args->num_m2s_rings == 0)
568     args->num_m2s_rings = MEMIF_DEFAULT_RX_QUEUES;
569
570   conn->args.num_s2m_rings = args->num_s2m_rings;
571   conn->args.num_m2s_rings = args->num_m2s_rings;
572   conn->args.buffer_size = args->buffer_size;
573   conn->args.log2_ring_size = args->log2_ring_size;
574   conn->args.is_master = args->is_master;
575   conn->args.mode = args->mode;
576   conn->msg_queue = NULL;
577   conn->regions = NULL;
578   conn->tx_queues = NULL;
579   conn->rx_queues = NULL;
580   conn->fd = -1;
581   conn->on_connect = on_connect;
582   conn->on_disconnect = on_disconnect;
583   conn->on_interrupt = on_interrupt;
584   conn->private_ctx = private_ctx;
585   memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
586
587   uint8_t l = strlen ((char *) args->interface_name);
588   strncpy ((char *) conn->args.interface_name, (char *) args->interface_name,
589            l);
590
591   l = strlen ((char *) args->instance_name);
592   strncpy ((char *) conn->args.instance_name, (char *) args->instance_name,
593            l);
594
595   /* allocate and initialize socket_filename so it can be copyed to sun_path
596      without memory leaks */
597   conn->args.socket_filename = malloc (sizeof (char *) * 108);
598   memset (conn->args.socket_filename, 0, 108 * sizeof (char *));
599
600   if (args->socket_filename)
601     {
602       if (conn->args.socket_filename == NULL)
603         {
604           err = memif_syscall_error_handler (errno);
605           goto error;
606         }
607       strncpy ((char *) conn->args.socket_filename,
608                (char *) args->socket_filename,
609                strlen ((char *) args->socket_filename));
610     }
611   else
612     {
613       uint16_t sdl = strlen (MEMIF_DEFAULT_SOCKET_DIR);
614       uint16_t sfl = strlen (MEMIF_DEFAULT_SOCKET_FILENAME);
615       if (conn->args.socket_filename == NULL)
616         {
617           err = memif_syscall_error_handler (errno);
618           goto error;
619         }
620       strncpy ((char *) conn->args.socket_filename,
621                MEMIF_DEFAULT_SOCKET_DIR, sdl);
622       conn->args.socket_filename[sdl] = '/';
623       strncpy ((char *) (conn->args.socket_filename + 1 + sdl),
624                MEMIF_DEFAULT_SOCKET_FILENAME, sfl);
625     }
626
627   if (args->secret)
628     {
629       l = strlen ((char *) args->secret);
630       strncpy ((char *) conn->args.secret, (char *) args->secret, l);
631     }
632
633   if (conn->args.is_master)
634     {
635       conn->run_args.buffer_size = conn->args.buffer_size;
636       memif_socket_t *ms;
637       memif_list_elt_t elt;
638       for (i = 0; i < lm->listener_list_len; i++)
639         {
640           if ((ms =
641                (memif_socket_t *) lm->listener_list[i].data_struct) != NULL)
642             {
643               if (strncmp
644                   ((char *) ms->filename, (char *) conn->args.socket_filename,
645                    strlen ((char *) ms->filename)) == 0)
646                 {
647                   /* add interface to listener socket */
648                   elt.key = conn->args.interface_id;
649                   *c = elt.data_struct = conn;
650                   add_list_elt (&elt, &ms->interface_list,
651                                 &ms->interface_list_len);
652                   ms->use_count++;
653                   conn->listener_fd = ms->fd;
654                   break;
655                 }
656             }
657           else
658             {
659               struct stat file_stat;
660               if (stat ((char *) conn->args.socket_filename, &file_stat) == 0)
661                 {
662                   if (S_ISSOCK (file_stat.st_mode))
663                     unlink ((char *) conn->args.socket_filename);
664                   else
665                     return memif_syscall_error_handler (errno);
666                 }
667               DBG ("creating socket file");
668               ms = malloc (sizeof (memif_socket_t));
669               ms->filename =
670                 malloc (strlen ((char *) conn->args.socket_filename) +
671                         sizeof (char));
672               memset (ms->filename, 0,
673                       strlen ((char *) conn->args.socket_filename) +
674                       sizeof (char));
675               strncpy ((char *) ms->filename,
676                        (char *) conn->args.socket_filename,
677                        strlen ((char *) conn->args.socket_filename));
678               ms->interface_list_len = 1;
679               ms->interface_list =
680                 malloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
681               ms->interface_list[0].key = -1;
682               ms->interface_list[0].data_struct = NULL;
683               struct sockaddr_un un = { 0 };
684               int on = 1;
685
686               ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
687               if (ms->fd < 0)
688                 {
689                   err = memif_syscall_error_handler (errno);
690                   goto error;
691                 }
692               DBG ("socket %d created", ms->fd);
693               un.sun_family = AF_UNIX;
694               strncpy ((char *) un.sun_path, (char *) ms->filename,
695                        sizeof (un.sun_path) - 1);
696               DBG ("sockopt");
697               if (setsockopt
698                   (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
699                 {
700                   err = memif_syscall_error_handler (errno);
701                   goto error;
702                 }
703               DBG ("bind");
704               if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
705                 {
706                   err = memif_syscall_error_handler (errno);
707                   goto error;
708                 }
709               DBG ("listen");
710               if (listen (ms->fd, 1) < 0)
711                 {
712                   err = memif_syscall_error_handler (errno);
713                   goto error;
714                 }
715               DBG ("stat");
716               if (stat ((char *) ms->filename, &file_stat) < 0)
717                 {
718                   err = memif_syscall_error_handler (errno);
719                   goto error;
720                 }
721
722               /* add interface to listener socket */
723               elt.key = conn->args.interface_id;
724               *c = elt.data_struct = conn;
725               add_list_elt (&elt, &ms->interface_list,
726                             &ms->interface_list_len);
727               ms->use_count = 1;
728               conn->listener_fd = ms->fd;
729
730               /* add listener socket to libmemif main */
731               elt.key = ms->fd;
732               elt.data_struct = ms;
733               add_list_elt (&elt, &lm->listener_list, &lm->listener_list_len);
734               lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_READ);
735               break;
736             }
737         }
738     }
739   else
740     {
741       if (lm->disconn_slaves == 0)
742         {
743           if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
744             {
745               err = memif_syscall_error_handler (errno);
746               goto error;
747             }
748         }
749
750       lm->disconn_slaves++;
751
752       list_elt.key = -1;
753       *c = list_elt.data_struct = conn;
754       if ((index =
755            add_list_elt (&list_elt, &lm->control_list,
756                          &lm->control_list_len)) < 0)
757         {
758           err = MEMIF_ERR_NOMEM;
759           goto error;
760         }
761     }
762
763   conn->index = index;
764
765   return 0;
766
767 error:
768   if (sockfd > 0)
769     close (sockfd);
770   sockfd = -1;
771   if (conn->args.socket_filename)
772     free (conn->args.socket_filename);
773   if (conn != NULL)
774     free (conn);
775   *c = conn = NULL;
776   return err;
777 }
778
779 int
780 memif_control_fd_handler (int fd, uint8_t events)
781 {
782   int i, rv, sockfd = -1, err = MEMIF_ERR_SUCCESS;      /* 0 */
783   uint16_t num;
784   memif_list_elt_t *e = NULL;
785   memif_connection_t *conn;
786   libmemif_main_t *lm = &libmemif_main;
787   if (fd == lm->timerfd)
788     {
789       uint64_t b;
790       ssize_t size;
791       size = read (fd, &b, sizeof (b));
792       for (i = 0; i < lm->control_list_len; i++)
793         {
794           if ((lm->control_list[i].key < 0)
795               && (lm->control_list[i].data_struct != NULL))
796             {
797               conn = lm->control_list[i].data_struct;
798               if (conn->args.is_master)
799                 continue;
800
801               struct sockaddr_un sun;
802               sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
803               if (sockfd < 0)
804                 {
805                   err = memif_syscall_error_handler (errno);
806                   goto error;
807                 }
808
809               sun.sun_family = AF_UNIX;
810
811               strncpy (sun.sun_path, conn->args.socket_filename,
812                        sizeof (sun.sun_path) - 1);
813
814               if (connect (sockfd, (struct sockaddr *) &sun,
815                            sizeof (struct sockaddr_un)) == 0)
816                 {
817                   conn->fd = sockfd;
818                   conn->read_fn = memif_conn_fd_read_ready;
819                   conn->write_fn = memif_conn_fd_write_ready;
820                   conn->error_fn = memif_conn_fd_error;
821
822                   lm->control_list[conn->index].key = conn->fd;
823
824                   lm->control_fd_update (sockfd,
825                                          MEMIF_FD_EVENT_READ |
826                                          MEMIF_FD_EVENT_WRITE);
827
828                   lm->disconn_slaves--;
829                   if (lm->disconn_slaves == 0)
830                     {
831                       if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL)
832                           < 0)
833                         {
834                           err = memif_syscall_error_handler (errno);
835                           goto error;
836                         }
837                     }
838                 }
839               else
840                 {
841                   err = memif_syscall_error_handler (errno);
842                   goto error;
843                 }
844             }
845         }
846     }
847   else
848     {
849       get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
850       if (e != NULL)
851         {
852           if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
853             {
854               num =
855                 (((memif_connection_t *) e->data_struct)->args.
856                  is_master) ? ((memif_connection_t *) e->data_struct)->
857                 run_args.num_s2m_rings : ((memif_connection_t *) e->
858                                           data_struct)->run_args.
859                 num_m2s_rings;
860               for (i = 0; i < num; i++)
861                 {
862                   if (((memif_connection_t *) e->data_struct)->rx_queues[i].
863                       int_fd == fd)
864                     {
865                       ((memif_connection_t *) e->
866                        data_struct)->on_interrupt ((void *) e->data_struct,
867                                                    ((memif_connection_t *)
868                                                     e->data_struct)->
869                                                    private_ctx, i);
870                       return MEMIF_ERR_SUCCESS;
871                     }
872                 }
873             }
874           return MEMIF_ERR_SUCCESS;
875         }
876       get_list_elt (&e, lm->listener_list, lm->listener_list_len, fd);
877       if (e != NULL)
878         {
879           memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
880           return MEMIF_ERR_SUCCESS;
881         }
882
883       get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
884       if (e != NULL)
885         {
886           memif_read_ready (fd);
887           return MEMIF_ERR_SUCCESS;
888         }
889
890       get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
891       if (e != NULL)
892         {
893           if (events & MEMIF_FD_EVENT_READ)
894             {
895               err =
896                 ((memif_connection_t *) e->data_struct)->read_fn (e->
897                                                                   data_struct);
898               if (err != MEMIF_ERR_SUCCESS)
899                 return err;
900             }
901           if (events & MEMIF_FD_EVENT_WRITE)
902             {
903               err =
904                 ((memif_connection_t *) e->data_struct)->write_fn (e->
905                                                                    data_struct);
906               if (err != MEMIF_ERR_SUCCESS)
907                 return err;
908             }
909           if (events & MEMIF_FD_EVENT_ERROR)
910             {
911               err =
912                 ((memif_connection_t *) e->data_struct)->error_fn (e->
913                                                                    data_struct);
914               if (err != MEMIF_ERR_SUCCESS)
915                 return err;
916             }
917         }
918     }
919
920   return MEMIF_ERR_SUCCESS;     /* 0 */
921
922 error:
923   if (sockfd > 0)
924     close (sockfd);
925   sockfd = -1;
926   return err;
927 }
928
929 int
930 memif_poll_event (int timeout)
931 {
932   libmemif_main_t *lm = &libmemif_main;
933   memif_list_elt_t *elt;
934   struct epoll_event evt, *e;
935   int en = 0, err = MEMIF_ERR_SUCCESS, i = 0;   /* 0 */
936   uint16_t num;
937   uint32_t events = 0;
938   uint64_t counter = 0;
939   ssize_t r = 0;
940   memset (&evt, 0, sizeof (evt));
941   evt.events = EPOLLIN | EPOLLOUT;
942   sigset_t sigset;
943   sigemptyset (&sigset);
944   en = epoll_pwait (memif_epfd, &evt, 1, timeout, &sigset);
945   if (en < 0)
946     {
947       err = errno;
948       DBG ("epoll_pwait: %s", strerror (err));
949       return memif_syscall_error_handler (err);
950     }
951   if (en > 0)
952     {
953       if (evt.data.fd == poll_cancel_fd)
954         {
955           r = read (evt.data.fd, &counter, sizeof (counter));
956           return MEMIF_ERR_POLL_CANCEL;
957         }
958       if (evt.events & EPOLLIN)
959         events |= MEMIF_FD_EVENT_READ;
960       if (evt.events & EPOLLOUT)
961         events |= MEMIF_FD_EVENT_WRITE;
962       if (evt.events & EPOLLERR)
963         events |= MEMIF_FD_EVENT_ERROR;
964       err = memif_control_fd_handler (evt.data.fd, events);
965       return err;
966     }
967   return 0;
968 }
969
970 int
971 memif_cancel_poll_event ()
972 {
973   uint64_t counter = 1;
974   ssize_t w = 0;
975
976   if (poll_cancel_fd == -1)
977     return 0;
978   w = write (poll_cancel_fd, &counter, sizeof (counter));
979   if (w < sizeof (counter))
980     return MEMIF_ERR_INT_WRITE;
981
982   return 0;
983 }
984
985 static void
986 memif_msg_queue_free (memif_msg_queue_elt_t ** e)
987 {
988   if (*e == NULL)
989     return;
990   memif_msg_queue_free (&(*e)->next);
991   free (*e);
992   *e = NULL;
993   return;
994 }
995
996 /* send disconnect msg and close interface */
997 int
998 memif_disconnect_internal (memif_connection_t * c)
999 {
1000   if (c == NULL)
1001     {
1002       DBG ("no connection");
1003       return MEMIF_ERR_NOCONN;
1004     }
1005   uint16_t num;
1006   int err = MEMIF_ERR_SUCCESS, i;       /* 0 */
1007   memif_queue_t *mq;
1008   libmemif_main_t *lm = &libmemif_main;
1009   memif_list_elt_t *e;
1010
1011   c->on_disconnect ((void *) c, c->private_ctx);
1012
1013   if (c->fd > 0)
1014     {
1015       memif_msg_send_disconnect (c->fd, "interface deleted", 0);
1016       lm->control_fd_update (c->fd, MEMIF_FD_EVENT_DEL);
1017       close (c->fd);
1018     }
1019   get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
1020   if (e != NULL)
1021     {
1022       if (c->args.is_master)
1023         free_list_elt (lm->control_list, lm->control_list_len, c->fd);
1024       e->key = c->fd = -1;
1025     }
1026
1027   if (c->tx_queues != NULL)
1028     {
1029       num =
1030         (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1031         num_s2m_rings;
1032       for (i = 0; i < num; i++)
1033         {
1034           mq = &c->tx_queues[i];
1035           if (mq != NULL)
1036             {
1037               if (mq->int_fd > 0)
1038                 close (mq->int_fd);
1039               free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1040                              mq->int_fd);
1041               mq->int_fd = -1;
1042             }
1043         }
1044       free (c->tx_queues);
1045       c->tx_queues = NULL;
1046     }
1047
1048   if (c->rx_queues != NULL)
1049     {
1050       num =
1051         (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1052         num_m2s_rings;
1053       for (i = 0; i < num; i++)
1054         {
1055           mq = &c->rx_queues[i];
1056           if (mq != NULL)
1057             {
1058               if (mq->int_fd > 0)
1059                 {
1060                   if (c->on_interrupt != NULL)
1061                     lm->control_fd_update (mq->int_fd, MEMIF_FD_EVENT_DEL);
1062                   close (mq->int_fd);
1063                 }
1064               free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1065                              mq->int_fd);
1066               mq->int_fd = -1;
1067             }
1068         }
1069       free (c->rx_queues);
1070       c->rx_queues = NULL;
1071     }
1072
1073   if (c->regions != NULL)
1074     {
1075       if (munmap (c->regions[0].shm, c->regions[0].region_size) < 0)
1076         return memif_syscall_error_handler (errno);
1077       if (c->regions[0].fd > 0)
1078         close (c->regions[0].fd);
1079       c->regions[0].fd = -1;
1080       free (c->regions);
1081       c->regions = NULL;
1082     }
1083
1084   memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
1085
1086   memif_msg_queue_free (&c->msg_queue);
1087
1088   if (!(c->args.is_master))
1089     {
1090       if (lm->disconn_slaves == 0)
1091         {
1092           if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1093             {
1094               err = memif_syscall_error_handler (errno);
1095               DBG_UNIX ("timerfd_settime: arm");
1096             }
1097         }
1098       lm->disconn_slaves++;
1099     }
1100
1101   return err;
1102 }
1103
1104 int
1105 memif_delete (memif_conn_handle_t * conn)
1106 {
1107   memif_connection_t *c = (memif_connection_t *) * conn;
1108   if (c == NULL)
1109     {
1110       DBG ("no connection");
1111       return MEMIF_ERR_NOCONN;
1112     }
1113   libmemif_main_t *lm = &libmemif_main;
1114   memif_list_elt_t *e = NULL;
1115   memif_socket_t *ms = NULL;
1116
1117   int err = MEMIF_ERR_SUCCESS;
1118
1119   if (c->fd > 0)
1120     {
1121       DBG ("DISCONNECTING");
1122       err = memif_disconnect_internal (c);
1123       if (err == MEMIF_ERR_NOCONN)
1124         return err;
1125     }
1126
1127   free_list_elt_ctx (lm->control_list, lm->control_list_len, c);
1128
1129   if (c->args.is_master)
1130     {
1131       get_list_elt (&e, lm->listener_list, lm->listener_list_len,
1132                     c->listener_fd);
1133       if (e != NULL)
1134         {
1135           ms = (memif_socket_t *) e->data_struct;
1136           ms->use_count--;
1137           free_list_elt (ms->interface_list, ms->interface_list_len,
1138                          c->args.interface_id);
1139           if (ms->use_count <= 0)
1140             {
1141               lm->control_fd_update (c->listener_fd, MEMIF_FD_EVENT_DEL);
1142               free_list_elt (lm->listener_list, lm->listener_list_len,
1143                              c->listener_fd);
1144               close (c->listener_fd);
1145               c->listener_fd = ms->fd = -1;
1146               free (ms->interface_list);
1147               ms->interface_list = NULL;
1148               free (ms->filename);
1149               ms->filename = NULL;
1150               free (ms);
1151               ms = NULL;
1152             }
1153         }
1154     }
1155   else
1156     {
1157       lm->disconn_slaves--;
1158       if (lm->disconn_slaves <= 0)
1159         {
1160           if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1161             {
1162               err = memif_syscall_error_handler (errno);
1163               DBG ("timerfd_settime: disarm");
1164             }
1165         }
1166     }
1167
1168   if (c->args.socket_filename)
1169     free (c->args.socket_filename);
1170   c->args.socket_filename = NULL;
1171
1172   free (c);
1173   c = NULL;
1174
1175   *conn = c;
1176   return err;
1177 }
1178
1179 int
1180 memif_connect1 (memif_connection_t * c)
1181 {
1182   libmemif_main_t *lm = &libmemif_main;
1183   memif_region_t *mr = c->regions;
1184   memif_queue_t *mq;
1185   int i;
1186   uint16_t num;
1187
1188   if (mr != NULL)
1189     {
1190       if (!mr->shm)
1191         {
1192           if (mr->fd < 0)
1193             return MEMIF_ERR_NO_SHMFD;
1194
1195           if ((mr->shm = mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
1196                                MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
1197             {
1198               return memif_syscall_error_handler (errno);
1199             }
1200         }
1201     }
1202
1203   num =
1204     (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1205     num_s2m_rings;
1206   for (i = 0; i < num; i++)
1207     {
1208       mq = &c->tx_queues[i];
1209       if (mq != NULL)
1210         {
1211           mq->ring = c->regions[mq->region].shm + mq->offset;
1212           if (mq->ring->cookie != MEMIF_COOKIE)
1213             {
1214               DBG ("wrong cookie on tx ring %u", i);
1215               return MEMIF_ERR_COOKIE;
1216             }
1217           mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1218             0;
1219         }
1220     }
1221   num =
1222     (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1223     num_m2s_rings;
1224   for (i = 0; i < num; i++)
1225     {
1226       mq = &c->rx_queues[i];
1227       if (mq != NULL)
1228         {
1229           mq->ring = c->regions[mq->region].shm + mq->offset;
1230           if (mq->ring->cookie != MEMIF_COOKIE)
1231             {
1232               DBG ("wrong cookie on rx ring %u", i);
1233               return MEMIF_ERR_COOKIE;
1234             }
1235           mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1236             0;
1237         }
1238     }
1239
1240   lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD);
1241
1242   return 0;
1243 }
1244
1245 int
1246 memif_init_regions_and_queues (memif_connection_t * conn)
1247 {
1248   memif_ring_t *ring = NULL;
1249   uint64_t buffer_offset;
1250   memif_region_t *r;
1251   int i, j;
1252   libmemif_main_t *lm = &libmemif_main;
1253   memif_list_elt_t e;
1254
1255   conn->regions = (memif_region_t *) malloc (sizeof (memif_region_t));
1256   if (conn->regions == NULL)
1257     return memif_syscall_error_handler (errno);
1258   r = conn->regions;
1259
1260   buffer_offset =
1261     (conn->run_args.num_s2m_rings +
1262      conn->run_args.num_m2s_rings) * (sizeof (memif_ring_t) +
1263                                       sizeof (memif_desc_t) *
1264                                       (1 << conn->run_args.log2_ring_size));
1265
1266   r->region_size = buffer_offset +
1267     conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1268     (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1269
1270   if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1271     return memif_syscall_error_handler (errno);
1272 /*
1273     if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
1274         return memif_syscall_error_handler (errno);
1275 */
1276   if ((ftruncate (r->fd, r->region_size)) == -1)
1277     return memif_syscall_error_handler (errno);
1278
1279   if ((r->shm = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
1280                       MAP_SHARED, r->fd, 0)) == MAP_FAILED)
1281     return memif_syscall_error_handler (errno);
1282
1283   for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1284     {
1285       ring = memif_get_ring (conn, MEMIF_RING_S2M, i);
1286       DBG ("RING: %p I: %d", ring, i);
1287       ring->head = ring->tail = 0;
1288       ring->cookie = MEMIF_COOKIE;
1289       ring->flags = 0;
1290       for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1291         {
1292           uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1293           ring->desc[j].region = 0;
1294           ring->desc[j].offset = buffer_offset +
1295             (uint32_t) (slot * conn->run_args.buffer_size);
1296           ring->desc[j].buffer_length = conn->run_args.buffer_size;
1297         }
1298     }
1299   for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1300     {
1301       ring = memif_get_ring (conn, MEMIF_RING_M2S, i);
1302       DBG ("RING: %p I: %d", ring, i);
1303       ring->head = ring->tail = 0;
1304       ring->cookie = MEMIF_COOKIE;
1305       ring->flags = 0;
1306       for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1307         {
1308           uint16_t slot =
1309             (i +
1310              conn->run_args.num_s2m_rings) *
1311             (1 << conn->run_args.log2_ring_size) + j;
1312           ring->desc[j].region = 0;
1313           ring->desc[j].offset = buffer_offset +
1314             (uint32_t) (slot * conn->run_args.buffer_size);
1315           ring->desc[j].buffer_length = conn->run_args.buffer_size;
1316         }
1317     }
1318   memif_queue_t *mq;
1319   mq =
1320     (memif_queue_t *) malloc (sizeof (memif_queue_t) *
1321                               conn->run_args.num_s2m_rings);
1322   if (mq == NULL)
1323     return memif_syscall_error_handler (errno);
1324   int x;
1325   for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1326     {
1327       if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1328         return memif_syscall_error_handler (errno);
1329       /* add int fd to interrupt fd list */
1330       e.key = mq[x].int_fd;
1331       e.data_struct = conn;
1332       add_list_elt (&e, &lm->interrupt_list, &lm->interrupt_list_len);
1333
1334       mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
1335       DBG ("RING: %p I: %d", mq[x].ring, x);
1336       mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1337       mq[x].region = 0;
1338       mq[x].offset =
1339         (void *) mq[x].ring - (void *) conn->regions[mq->region].shm;
1340       mq[x].last_head = 0;
1341       mq[x].alloc_bufs = 0;
1342     }
1343   conn->tx_queues = mq;
1344
1345   mq =
1346     (memif_queue_t *) malloc (sizeof (memif_queue_t) *
1347                               conn->run_args.num_m2s_rings);
1348   if (mq == NULL)
1349     return memif_syscall_error_handler (errno);
1350   for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1351     {
1352       if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1353         return memif_syscall_error_handler (errno);
1354       /* add int fd to interrupt fd list */
1355       e.key = mq[x].int_fd;
1356       e.data_struct = conn;
1357       add_list_elt (&e, &lm->interrupt_list, &lm->interrupt_list_len);
1358
1359       mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
1360       DBG ("RING: %p I: %d", mq[x].ring, x);
1361       mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1362       mq[x].region = 0;
1363       mq[x].offset =
1364         (void *) mq[x].ring - (void *) conn->regions[mq->region].shm;
1365       mq[x].last_head = 0;
1366       mq[x].alloc_bufs = 0;
1367     }
1368   conn->rx_queues = mq;
1369
1370   return 0;
1371 }
1372
1373 int
1374 memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
1375                     memif_buffer_t * bufs, uint16_t count,
1376                     uint16_t * count_out, uint16_t size)
1377 {
1378   memif_connection_t *c = (memif_connection_t *) conn;
1379   if (c == NULL)
1380     return MEMIF_ERR_NOCONN;
1381   if (c->fd < 0)
1382     return MEMIF_ERR_DISCONNECTED;
1383   uint8_t num =
1384     (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1385     num_s2m_rings;
1386   if (qid >= num)
1387     return MEMIF_ERR_QID;
1388   memif_queue_t *mq = &c->tx_queues[qid];
1389   memif_ring_t *ring = mq->ring;
1390   memif_buffer_t *b0, *b1;
1391   uint8_t chain_buf0, chain_buf1;
1392   uint16_t mask = (1 << mq->log2_ring_size) - 1;
1393   uint16_t s0, s1, ns;
1394   *count_out = 0;
1395   int i, err = MEMIF_ERR_SUCCESS;       /* 0 */
1396
1397   if (ring->tail != ring->head)
1398     {
1399       if (ring->head > ring->tail)
1400         ns = (1 << mq->log2_ring_size) - ring->head + ring->tail;
1401       else
1402         ns = ring->tail - ring->head;
1403     }
1404   else
1405     ns = (1 << mq->log2_ring_size);
1406
1407   /* (head == tail) ? receive function will asume that no packets are available */
1408   ns -= 1;
1409
1410   while (count && ns)
1411     {
1412       while ((count > 2) && (ns > 2))
1413         {
1414           s0 = (ring->head + mq->alloc_bufs) & mask;
1415           chain_buf0 = size / ring->desc[s0].buffer_length;
1416           if (((size % ring->desc[s0].buffer_length) != 0) || (size == 0))
1417             chain_buf0++;
1418
1419           if (chain_buf0 > ns)
1420             break;
1421
1422           s1 = (ring->head + mq->alloc_bufs + chain_buf0) & mask;
1423           chain_buf1 = size / ring->desc[s1].buffer_length;
1424           if (((size % ring->desc[s1].buffer_length) != 0) || (size == 0))
1425             chain_buf1++;
1426
1427           if ((chain_buf0 + chain_buf1) > ns)
1428             break;
1429
1430           b0 = (bufs + *count_out);
1431           b1 = (bufs + *count_out + 1);
1432
1433           b0->desc_index = s0;
1434           b1->desc_index = s1;
1435           ring->desc[s0].flags = 0;
1436           ring->desc[s1].flags = 0;
1437           b0->buffer_len = ring->desc[s0].buffer_length * chain_buf0;
1438           b1->buffer_len = ring->desc[s1].buffer_length * chain_buf1;
1439           /* TODO: support multiple regions -> ring descriptor contains region index */
1440           b0->data = c->regions->shm + ring->desc[s0].offset;
1441           b1->data = c->regions->shm + ring->desc[s1].offset;
1442
1443           for (i = 0; i < (memif_min (chain_buf0, chain_buf1) - 1); i++)
1444             {
1445               ring->desc[(s0 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
1446               ring->desc[(s1 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
1447               DBG ("allocating chained buffers");
1448             }
1449
1450           if (chain_buf0 > chain_buf1)
1451             {
1452               for (; i < (chain_buf0 - 1); i++)
1453                 ring->desc[(s0 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
1454             }
1455           else
1456             {
1457               for (; i < (chain_buf1 - 1); i++)
1458                 ring->desc[(s1 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
1459             }
1460
1461           mq->alloc_bufs += chain_buf0 + chain_buf1;
1462
1463           DBG ("allocated ring slots %u, %u", s0, s1);
1464           count -= 2;
1465           ns -= chain_buf0 + chain_buf1;
1466           *count_out += 2;
1467         }
1468       s0 = (ring->head + mq->alloc_bufs) & mask;
1469
1470       b0 = (bufs + *count_out);
1471
1472       chain_buf0 = size / ring->desc[s0].buffer_length;
1473       if (((size % ring->desc[s0].buffer_length) != 0) || (size == 0))
1474         chain_buf0++;
1475
1476       if (chain_buf0 > ns)
1477         break;
1478
1479       b0->desc_index = s0;
1480       ring->desc[s0].flags = 0;
1481       b0->buffer_len = ring->desc[s0].buffer_length * chain_buf0;
1482       b0->data = c->regions->shm + ring->desc[s0].offset;
1483
1484       for (i = 0; i < (chain_buf0 - 1); i++)
1485         {
1486           ring->desc[(s0 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
1487           DBG ("allocating chained buffers");
1488         }
1489
1490       mq->alloc_bufs += chain_buf0;
1491
1492       DBG ("allocated ring slot %u", s0);
1493       count--;
1494       ns -= chain_buf0;
1495       *count_out += 1;
1496     }
1497
1498   DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1499        mq->alloc_bufs);
1500
1501   if (count)
1502     {
1503       DBG ("ring buffer full! qid: %u", qid);
1504       err = MEMIF_ERR_NOBUF_RING;
1505     }
1506
1507   return err;
1508 }
1509
1510 int
1511 memif_buffer_free (memif_conn_handle_t conn, uint16_t qid,
1512                    memif_buffer_t * bufs, uint16_t count,
1513                    uint16_t * count_out)
1514 {
1515   memif_connection_t *c = (memif_connection_t *) conn;
1516   if (c == NULL)
1517     return MEMIF_ERR_NOCONN;
1518   if (c->fd < 0)
1519     return MEMIF_ERR_DISCONNECTED;
1520   uint8_t num =
1521     (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1522     num_m2s_rings;
1523   if (qid >= num)
1524     return MEMIF_ERR_QID;
1525   libmemif_main_t *lm = &libmemif_main;
1526   memif_queue_t *mq = &c->rx_queues[qid];
1527   memif_ring_t *ring = mq->ring;
1528   uint16_t tail = ring->tail;
1529   uint16_t mask = (1 << mq->log2_ring_size) - 1;
1530   uint8_t chain_buf0, chain_buf1;
1531   memif_buffer_t *b0, *b1;
1532   *count_out = 0;
1533
1534   if (mq->alloc_bufs < count)
1535     count = mq->alloc_bufs;
1536
1537   while (count)
1538     {
1539       while (count > 2)
1540         {
1541           b0 = (bufs + *count_out);
1542           b1 = (bufs + *count_out + 1);
1543           chain_buf0 =
1544             b0->buffer_len / ring->desc[b0->desc_index].buffer_length;
1545           if ((b0->buffer_len % ring->desc[b0->desc_index].buffer_length) !=
1546               0)
1547             chain_buf0++;
1548           chain_buf1 =
1549             b1->buffer_len / ring->desc[b1->desc_index].buffer_length;
1550           if ((b1->buffer_len % ring->desc[b1->desc_index].buffer_length) !=
1551               0)
1552             chain_buf1++;
1553           tail = (b1->desc_index + chain_buf1) & mask;
1554           b0->data = NULL;
1555           b1->data = NULL;
1556
1557           count -= 2;
1558           *count_out += 2;
1559           mq->alloc_bufs -= chain_buf0 + chain_buf1;
1560         }
1561       b0 = (bufs + *count_out);
1562       chain_buf0 = b0->buffer_len / ring->desc[b0->desc_index].buffer_length;
1563       if ((b0->buffer_len % ring->desc[b0->desc_index].buffer_length) != 0)
1564         chain_buf0++;
1565       tail = (b0->desc_index + chain_buf0) & mask;
1566       b0->data = NULL;
1567
1568       count--;
1569       *count_out += 1;
1570       mq->alloc_bufs -= chain_buf0;
1571     }
1572   MEMIF_MEMORY_BARRIER ();
1573   ring->tail = tail;
1574   DBG ("tail: %u", ring->tail);
1575
1576   return MEMIF_ERR_SUCCESS;     /* 0 */
1577 }
1578
1579 int
1580 memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
1581                 memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
1582 {
1583   memif_connection_t *c = (memif_connection_t *) conn;
1584   if (c == NULL)
1585     return MEMIF_ERR_NOCONN;
1586   if (c->fd < 0)
1587     return MEMIF_ERR_DISCONNECTED;
1588   uint8_t num =
1589     (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1590     num_s2m_rings;
1591   if (qid >= num)
1592     return MEMIF_ERR_QID;
1593   memif_queue_t *mq = &c->tx_queues[qid];
1594   memif_ring_t *ring = mq->ring;
1595   uint16_t head = ring->head;
1596   uint16_t mask = (1 << mq->log2_ring_size) - 1;
1597   uint8_t chain_buf0, chain_buf1;
1598   *tx = 0;
1599   uint16_t curr_buf = 0;
1600   memif_buffer_t *b0, *b1;
1601   int i;
1602
1603   while (count)
1604     {
1605       while (count > 2)
1606         {
1607           b0 = (bufs + curr_buf);
1608           b1 = (bufs + curr_buf + 1);
1609           chain_buf0 =
1610             b0->buffer_len / ring->desc[b0->desc_index].buffer_length;
1611           if ((b0->buffer_len % ring->desc[b0->desc_index].buffer_length) !=
1612               0)
1613             chain_buf0++;
1614
1615           chain_buf1 =
1616             b1->buffer_len / ring->desc[b1->desc_index].buffer_length;
1617           if ((b1->buffer_len % ring->desc[b1->desc_index].buffer_length) !=
1618               0)
1619             chain_buf1++;
1620
1621           for (i = 0; i < memif_min (chain_buf0, chain_buf1); i++)
1622             {
1623               /* b0 */
1624               if (b0->data_len >
1625                   ring->desc[(b0->desc_index + i) & mask].buffer_length)
1626                 {
1627                   b0->data_len -=
1628                     ring->desc[(b0->desc_index + i) & mask].length =
1629                     ring->desc[(b0->desc_index + i) & mask].buffer_length;
1630                 }
1631               else
1632                 {
1633                   ring->desc[(b0->desc_index + i) & mask].length =
1634                     b0->data_len;
1635                   b0->data_len = 0;
1636                 }
1637               /* b1 */
1638               if (b1->data_len >
1639                   ring->desc[(b1->desc_index + i) & mask].buffer_length)
1640                 {
1641                   b1->data_len -=
1642                     ring->desc[(b1->desc_index + i) & mask].length =
1643                     ring->desc[(b1->desc_index + i) & mask].buffer_length;
1644                 }
1645               else
1646                 {
1647                   ring->desc[(b1->desc_index + i) & mask].length =
1648                     b1->data_len;
1649                   b1->data_len = 0;
1650                 }
1651 #ifdef MEMIF_DBG_SHM
1652               print_bytes (b0->data +
1653                            ring->desc[(b0->desc_index +
1654                                        i) & mask].buffer_length *
1655                            (chain_buf0 - 1),
1656                            ring->desc[(b0->desc_index +
1657                                        i) & mask].buffer_length, DBG_TX_BUF);
1658               print_bytes (b1->data +
1659                            ring->desc[(b1->desc_index +
1660                                        i) & mask].buffer_length *
1661                            (chain_buf1 - 1),
1662                            ring->desc[(b1->desc_index +
1663                                        i) & mask].buffer_length, DBG_TX_BUF);
1664 #endif /* MEMIF_DBG_SHM */
1665             }
1666
1667           if (chain_buf0 > chain_buf1)
1668             {
1669               for (; i < chain_buf0; i++)
1670                 {
1671                   if (b0->data_len >
1672                       ring->desc[(b0->desc_index + i) & mask].buffer_length)
1673                     {
1674                       b0->data_len -=
1675                         ring->desc[(b0->desc_index + i) & mask].length =
1676                         ring->desc[(b0->desc_index + i) & mask].buffer_length;
1677                     }
1678                   else
1679                     {
1680                       ring->desc[(b0->desc_index + i) & mask].length =
1681                         b0->data_len;
1682                       b0->data_len = 0;
1683                     }
1684 #ifdef MEMIF_DBG_SHM
1685                   print_bytes (b0->data +
1686                                ring->desc[(b0->desc_index +
1687                                            i) & mask].buffer_length *
1688                                (chain_buf0 - 1),
1689                                ring->desc[(b0->desc_index +
1690                                            i) & mask].buffer_length,
1691                                DBG_TX_BUF);
1692 #endif /* MEMIF_DBG_SHM */
1693                 }
1694             }
1695           else
1696             {
1697               for (; i < chain_buf1; i++)
1698                 {
1699                   if (b1->data_len >
1700                       ring->desc[(b1->desc_index + i) & mask].buffer_length)
1701                     {
1702                       b1->data_len -=
1703                         ring->desc[(b1->desc_index + i) & mask].length =
1704                         ring->desc[(b1->desc_index + i) & mask].buffer_length;
1705                     }
1706                   else
1707                     {
1708                       ring->desc[(b1->desc_index + i) & mask].length =
1709                         b1->data_len;
1710                       b1->data_len = 0;
1711                     }
1712 #ifdef MEMIF_DBG_SHM
1713                   print_bytes (b1->data +
1714                                ring->desc[(b1->desc_index +
1715                                            i) & mask].buffer_length *
1716                                (chain_buf1 - 1),
1717                                ring->desc[(b1->desc_index +
1718                                            i) & mask].buffer_length,
1719                                DBG_TX_BUF);
1720 #endif /* MEMIF_DBG_SHM */
1721                 }
1722             }
1723
1724           head = (b1->desc_index + chain_buf1) & mask;
1725
1726           b0->data = NULL;
1727 #ifdef MEMIF_DBG
1728           if (b0->data_len != 0)
1729             DBG ("invalid b0 data length!");
1730 #endif /* MEMIF_DBG */
1731           b1->data = NULL;
1732 #ifdef MEMIF_DBG
1733           if (b1->data_len != 0)
1734             DBG ("invalid b1 data length!");
1735 #endif /* MEMIF_DBG */
1736
1737           count -= 2;
1738           *tx += chain_buf0 + chain_buf1;
1739           curr_buf += 2;
1740         }
1741
1742       b0 = (bufs + curr_buf);
1743       chain_buf0 = b0->buffer_len / ring->desc[b0->desc_index].buffer_length;
1744       if ((b0->buffer_len % ring->desc[b0->desc_index].buffer_length) != 0)
1745         chain_buf0++;
1746
1747       for (i = 0; i < chain_buf0; i++)
1748         {
1749           if (b0->data_len >
1750               ring->desc[(b0->desc_index + i) & mask].buffer_length)
1751             {
1752               b0->data_len -= ring->desc[(b0->desc_index + i) & mask].length =
1753                 ring->desc[(b0->desc_index + i) & mask].buffer_length;
1754             }
1755           else
1756             {
1757               ring->desc[(b0->desc_index + i) & mask].length = b0->data_len;
1758               b0->data_len = 0;
1759             }
1760 #ifdef MEMIF_DBG_SHM
1761           print_bytes (b0->data +
1762                        ring->desc[(b0->desc_index + i) & mask].buffer_length *
1763                        (chain_buf0 - 1),
1764                        ring->desc[(b0->desc_index + i) & mask].buffer_length,
1765                        DBG_TX_BUF);
1766 #endif /* MEMIF_DBG_SHM */
1767         }
1768
1769       head = (b0->desc_index + chain_buf0) & mask;
1770
1771       b0->data = NULL;
1772 #ifdef MEMIF_DBG
1773       if (b0->data_len != 0)
1774         DBG ("invalid b0 data length!");
1775 #endif /* MEMIF_DBG */
1776
1777       count--;
1778       *tx += chain_buf0;
1779       curr_buf++;
1780     }
1781   MEMIF_MEMORY_BARRIER ();
1782   ring->head = head;
1783
1784   mq->alloc_bufs -= *tx;
1785
1786   /* TODO: return num of buffers and packets */
1787   *tx = curr_buf;
1788
1789   if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
1790     {
1791       uint64_t a = 1;
1792       int r = write (mq->int_fd, &a, sizeof (a));
1793       if (r < 0)
1794         return MEMIF_ERR_INT_WRITE;
1795     }
1796
1797   return MEMIF_ERR_SUCCESS;     /* 0 */
1798 }
1799
1800 int
1801 memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
1802                 memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
1803 {
1804   memif_connection_t *c = (memif_connection_t *) conn;
1805   if (c == NULL)
1806     return MEMIF_ERR_NOCONN;
1807   if (c->fd < 0)
1808     return MEMIF_ERR_DISCONNECTED;
1809   uint8_t num =
1810     (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1811     num_m2s_rings;
1812   if (qid >= num)
1813     return MEMIF_ERR_QID;
1814   memif_queue_t *mq = &c->rx_queues[qid];
1815   memif_ring_t *ring = mq->ring;
1816   uint16_t head = ring->head;
1817   uint16_t ns;
1818   uint16_t mask = (1 << mq->log2_ring_size) - 1;
1819   memif_buffer_t *b0, *b1;
1820   uint16_t curr_buf = 0;
1821   *rx = 0;
1822   int i;
1823
1824   uint64_t b;
1825   ssize_t r = read (mq->int_fd, &b, sizeof (b));
1826   if ((r == -1) && (errno != EAGAIN))
1827     return memif_syscall_error_handler (errno);
1828
1829   if (head == mq->last_head)
1830     return 0;
1831
1832   if (head > mq->last_head)
1833     ns = head - mq->last_head;
1834   else
1835     ns = (1 << mq->log2_ring_size) - mq->last_head + head;
1836
1837   while (ns && count)
1838     {
1839       DBG ("ns: %u, count: %u", ns, count);
1840       while ((ns > 2) && (count > 2))
1841         {
1842           b0 = (bufs + curr_buf);
1843           b1 = (bufs + curr_buf + 1);
1844
1845           b0->desc_index = mq->last_head;
1846           i = 0;
1847           b0->data_len = 0;
1848           b0->buffer_len = 0;
1849
1850           b0->data = memif_get_buffer (conn, ring, mq->last_head);
1851           b0->data_len += ring->desc[mq->last_head].length;
1852           b0->buffer_len += ring->desc[mq->last_head].buffer_length;
1853 #ifdef MEMIF_DBG_SHM
1854           print_bytes (b0->data +
1855                        ring->desc[b0->desc_index].buffer_length * i++,
1856                        ring->desc[b0->desc_index].buffer_length, DBG_TX_BUF);
1857 #endif /* MEMIF_DBG_SHM */
1858           ns--;
1859           *rx += 1;
1860           while (ring->desc[mq->last_head].flags & MEMIF_DESC_FLAG_NEXT)
1861             {
1862               ring->desc[mq->last_head].flags &= ~MEMIF_DESC_FLAG_NEXT;
1863               mq->last_head = (mq->last_head + 1) & mask;
1864               b0->data_len += ring->desc[mq->last_head].length;
1865               b0->buffer_len += ring->desc[mq->last_head].buffer_length;
1866 #ifdef MEMIF_DBG_SHM
1867               print_bytes (b0->data +
1868                            ring->desc[b0->desc_index].buffer_length * i++,
1869                            ring->desc[b0->desc_index].buffer_length,
1870                            DBG_TX_BUF);
1871 #endif /* MEMIF_DBG_SHM */
1872               ns--;
1873               *rx += 1;
1874             }
1875           mq->last_head = (mq->last_head + 1) & mask;
1876
1877           b1->desc_index = mq->last_head;
1878           i = 0;
1879           b1->data_len = 0;
1880           b1->buffer_len = 0;
1881
1882           b1->data = memif_get_buffer (conn, ring, mq->last_head);
1883           b1->data_len += ring->desc[mq->last_head].length;
1884           b1->buffer_len += ring->desc[mq->last_head].buffer_length;
1885 #ifdef MEMIF_DBG_SHM
1886           print_bytes (b1->data +
1887                        ring->desc[b1->desc_index].buffer_length * i++,
1888                        ring->desc[b1->desc_index].buffer_length, DBG_TX_BUF);
1889 #endif /* MEMIF_DBG_SHM */
1890           ns--;
1891           *rx += 1;
1892           while (ring->desc[mq->last_head].flags & MEMIF_DESC_FLAG_NEXT)
1893             {
1894               ring->desc[mq->last_head].flags &= ~MEMIF_DESC_FLAG_NEXT;
1895               mq->last_head = (mq->last_head + 1) & mask;
1896               b1->data_len += ring->desc[mq->last_head].length;
1897               b1->buffer_len += ring->desc[mq->last_head].buffer_length;
1898 #ifdef MEMIF_DBG_SHM
1899               print_bytes (b1->data +
1900                            ring->desc[b1->desc_index].buffer_length * i++,
1901                            ring->desc[b1->desc_index].buffer_length,
1902                            DBG_TX_BUF);
1903 #endif /* MEMIF_DBG_SHM */
1904               ns--;
1905               *rx += 1;
1906             }
1907           mq->last_head = (mq->last_head + 1) & mask;
1908
1909           count -= 2;
1910           curr_buf += 2;
1911         }
1912       b0 = (bufs + curr_buf);
1913
1914       b0->desc_index = mq->last_head;
1915       i = 0;
1916       b0->data_len = 0;
1917       b0->buffer_len = 0;
1918
1919       b0->data = memif_get_buffer (conn, ring, mq->last_head);
1920       b0->data_len += ring->desc[mq->last_head].length;
1921       b0->buffer_len += ring->desc[mq->last_head].buffer_length;
1922 #ifdef MEMIF_DBG_SHM
1923       print_bytes (b0->data +
1924                    ring->desc[b0->desc_index].buffer_length * i++,
1925                    ring->desc[b0->desc_index].buffer_length, DBG_TX_BUF);
1926 #endif /* MEMIF_DBG_SHM */
1927       ns--;
1928       *rx += 1;
1929
1930       while (ring->desc[mq->last_head].flags & MEMIF_DESC_FLAG_NEXT)
1931         {
1932           ring->desc[mq->last_head].flags &= ~MEMIF_DESC_FLAG_NEXT;
1933           mq->last_head = (mq->last_head + 1) & mask;
1934           b0->data_len += ring->desc[mq->last_head].length;
1935           b0->buffer_len += ring->desc[mq->last_head].buffer_length;
1936 #ifdef MEMIF_DBG_SHM
1937           print_bytes (b0->data +
1938                        ring->desc[b0->desc_index].buffer_length * i++,
1939                        ring->desc[b0->desc_index].buffer_length, DBG_TX_BUF);
1940 #endif /* MEMIF_DBG_SHM */
1941           ns--;
1942           *rx += 1;
1943         }
1944       mq->last_head = (mq->last_head + 1) & mask;
1945
1946       count--;
1947       curr_buf++;
1948     }
1949
1950   mq->alloc_bufs += *rx;
1951
1952   /* TODO: return num of buffers and packets */
1953   *rx = curr_buf;
1954
1955   if (ns)
1956     {
1957       DBG ("not enough buffers!");
1958       return MEMIF_ERR_NOBUF;
1959     }
1960
1961   return MEMIF_ERR_SUCCESS;     /* 0 */
1962 }
1963
1964 int
1965 memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
1966                    char *buf, ssize_t buflen)
1967 {
1968   memif_connection_t *c = (memif_connection_t *) conn;
1969   if (c == NULL)
1970     return MEMIF_ERR_NOCONN;
1971
1972   int err = MEMIF_ERR_SUCCESS, i;
1973   ssize_t l0, l1, total_l;
1974   l0 = 0;
1975
1976   l1 = strlen ((char *) c->args.interface_name);
1977   if (l0 + l1 < buflen)
1978     {
1979       md->if_name = strcpy (buf + l0, (char *) c->args.interface_name);
1980       l0 += l1 + 1;
1981     }
1982   else
1983     err = MEMIF_ERR_NOBUF_DET;
1984
1985   l1 = strlen ((char *) c->args.instance_name);
1986   if (l0 + l1 < buflen)
1987     {
1988       md->inst_name = strcpy (buf + l0, (char *) c->args.instance_name);
1989       l0 += l1 + 1;
1990     }
1991   else
1992     err = MEMIF_ERR_NOBUF_DET;
1993
1994   l1 = strlen ((char *) c->remote_if_name);
1995   if (l0 + l1 < buflen)
1996     {
1997       md->remote_if_name = strcpy (buf + l0, (char *) c->remote_if_name);
1998       l0 += l1 + 1;
1999     }
2000   else
2001     err = MEMIF_ERR_NOBUF_DET;
2002
2003   l1 = strlen ((char *) c->remote_name);
2004   if (l0 + l1 < buflen)
2005     {
2006       md->remote_inst_name = strcpy (buf + l0, (char *) c->remote_name);
2007       l0 += l1 + 1;
2008     }
2009   else
2010     err = MEMIF_ERR_NOBUF_DET;
2011
2012   md->id = c->args.interface_id;
2013
2014   if (c->args.secret)
2015     {
2016       l1 = strlen ((char *) c->args.secret);
2017       if (l0 + l1 < buflen)
2018         {
2019           md->secret = strcpy (buf + l0, (char *) c->args.secret);
2020           l0 += l1 + 1;
2021         }
2022       else
2023         err = MEMIF_ERR_NOBUF_DET;
2024     }
2025
2026   md->role = (c->args.is_master) ? 0 : 1;
2027   md->mode = c->args.mode;
2028
2029   l1 = strlen ((char *) c->args.socket_filename);
2030   if (l0 + l1 < buflen)
2031     {
2032       md->socket_filename =
2033         strcpy (buf + l0, (char *) c->args.socket_filename);
2034       l0 += l1 + 1;
2035     }
2036   else
2037     err = MEMIF_ERR_NOBUF_DET;
2038
2039   md->rx_queues_num =
2040     (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
2041     num_m2s_rings;
2042
2043   l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
2044   if (l0 + l1 <= buflen)
2045     {
2046       md->rx_queues = (memif_queue_details_t *) buf + l0;
2047       l0 += l1;
2048     }
2049   else
2050     err = MEMIF_ERR_NOBUF_DET;
2051
2052   for (i = 0; i < md->rx_queues_num; i++)
2053     {
2054       md->rx_queues[i].qid = i;
2055       md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
2056       md->rx_queues[i].buffer_size = c->run_args.buffer_size;
2057     }
2058
2059   md->tx_queues_num =
2060     (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
2061     num_s2m_rings;
2062
2063   l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
2064   if (l0 + l1 <= buflen)
2065     {
2066       md->tx_queues = (memif_queue_details_t *) buf + l0;
2067       l0 += l1;
2068     }
2069   else
2070     err = MEMIF_ERR_NOBUF_DET;
2071
2072   for (i = 0; i < md->tx_queues_num; i++)
2073     {
2074       md->tx_queues[i].qid = i;
2075       md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
2076       md->tx_queues[i].buffer_size = c->run_args.buffer_size;
2077     }
2078
2079   md->link_up_down = (c->fd > 0) ? 1 : 0;
2080
2081   return err;                   /* 0 */
2082 }
2083
2084 int
2085 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
2086 {
2087   memif_connection_t *c = (memif_connection_t *) conn;
2088   *efd = -1;
2089   if (c == NULL)
2090     return MEMIF_ERR_NOCONN;
2091   if (c->fd < 0)
2092     return MEMIF_ERR_DISCONNECTED;
2093   uint8_t num =
2094     (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
2095     num_m2s_rings;
2096   if (qid >= num)
2097     return MEMIF_ERR_QID;
2098
2099   *efd = c->rx_queues[qid].int_fd;
2100
2101   return MEMIF_ERR_SUCCESS;
2102 }
2103
2104 int
2105 memif_cleanup ()
2106 {
2107   libmemif_main_t *lm = &libmemif_main;
2108   if (lm->app_name)
2109     free (lm->app_name);
2110   lm->app_name = NULL;
2111   if (lm->control_list)
2112     free (lm->control_list);
2113   lm->control_list = NULL;
2114   if (lm->interrupt_list)
2115     free (lm->interrupt_list);
2116   lm->interrupt_list = NULL;
2117   if (lm->listener_list)
2118     free (lm->listener_list);
2119   lm->listener_list = NULL;
2120   if (lm->pending_list)
2121     free (lm->pending_list);
2122   lm->pending_list = NULL;
2123   if (poll_cancel_fd != -1)
2124     close (poll_cancel_fd);
2125
2126   return MEMIF_ERR_SUCCESS;     /* 0 */
2127 }