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