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