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