FD.io VPP  v20.05.1-5-g09f167997
Vector Packet Processing
socket.c
Go to the documentation of this file.
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 <sys/socket.h>
20 #include <sys/types.h>
21 #include <sys/un.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <net/if.h>
26 #include <sys/ioctl.h>
27 #include <sys/uio.h>
28 #include <sys/mman.h>
29 #include <sys/prctl.h>
30 #include <fcntl.h>
31 #include <errno.h>
32 
33 #include <socket.h>
34 #include <memif.h>
35 #include <memif_private.h>
36 
37 /* sends msg to socket */
38 static_fn int
39 memif_msg_send (int fd, memif_msg_t * msg, int afd)
40 {
41  struct msghdr mh = { 0 };
42  struct iovec iov[1];
43  char ctl[CMSG_SPACE (sizeof (int))];
44  int rv, err = MEMIF_ERR_SUCCESS; /* 0 */
45 
46  iov[0].iov_base = (void *) msg;
47  iov[0].iov_len = sizeof (memif_msg_t);
48  mh.msg_iov = iov;
49  mh.msg_iovlen = 1;
50 
51  if (afd > 0)
52  {
53  struct cmsghdr *cmsg;
54  memset (&ctl, 0, sizeof (ctl));
55  mh.msg_control = ctl;
56  mh.msg_controllen = sizeof (ctl);
57  cmsg = CMSG_FIRSTHDR (&mh);
58  cmsg->cmsg_len = CMSG_LEN (sizeof (int));
59  cmsg->cmsg_level = SOL_SOCKET;
60  cmsg->cmsg_type = SCM_RIGHTS;
61  memcpy (CMSG_DATA (cmsg), &afd, sizeof (int));
62  }
63  rv = sendmsg (fd, &mh, 0);
64  if (rv < 0)
65  err = memif_syscall_error_handler (errno);
66  DBG ("Message type %u sent", msg->type);
67  return err;
68 }
69 
70 /* response from memif master - master is ready to handle next message */
71 static_fn int
73 {
74  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
77  if (e == NULL)
78  return memif_syscall_error_handler (errno);
79 
80  memset (&e->msg, 0, sizeof (e->msg));
82  e->fd = -1;
83 
84  e->next = NULL;
85  if (c->msg_queue == NULL)
86  {
87  c->msg_queue = e;
88  return MEMIF_ERR_SUCCESS; /* 0 */
89  }
90 
91  memif_msg_queue_elt_t *cur = c->msg_queue;
92  while (cur->next != NULL)
93  {
94  cur = cur->next;
95  }
96  cur->next = e;
97 
98  return MEMIF_ERR_SUCCESS; /* 0 */
99 }
100 
101 static_fn int
103 {
104  memif_msg_t msg = { 0 };
105  memif_msg_hello_t *h = &msg.hello;
113 
114  strncpy ((char *) h->name, (char *) lm->app_name,
115  strlen ((char *) lm->app_name));
116 
117  /* msg hello is not enqueued but sent directly,
118  because it is the first msg to be sent */
119  return memif_msg_send (fd, &msg, -1);
120 }
121 
122 /* send id and secret (optional) for interface identification */
123 static_fn int
125 {
126  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
129  if (e == NULL)
130  return memif_syscall_error_handler (errno);
131  memset (e, 0, sizeof (memif_msg_queue_elt_t));
132 
133  memset (&e->msg, 0, sizeof (e->msg));
134  memif_msg_init_t *i = &e->msg.init;
135 
137  e->fd = -1;
138  i->version = MEMIF_VERSION;
139  i->id = c->args.interface_id;
140  i->mode = c->args.mode;
141 
142  strncpy ((char *) i->name, (char *) lm->app_name,
143  strlen ((char *) lm->app_name));
144  if (strlen ((char *) c->args.secret) > 0)
145  strncpy ((char *) i->secret, (char *) c->args.secret, sizeof (i->secret));
146 
147  e->next = NULL;
148  if (c->msg_queue == NULL)
149  {
150  c->msg_queue = e;
151  return MEMIF_ERR_SUCCESS; /* 0 */
152  }
153 
154  memif_msg_queue_elt_t *cur = c->msg_queue;
155  while (cur->next != NULL)
156  {
157  cur = cur->next;
158  }
159  cur->next = e;
160 
161  return MEMIF_ERR_SUCCESS; /* 0 */
162 }
163 
164 /* send information about region specified by region_index */
165 static_fn int
167 {
168  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
169  memif_region_t *mr = &c->regions[region_index];
170 
173  if (e == NULL)
174  return memif_syscall_error_handler (errno);
175 
176  memset (&e->msg, 0, sizeof (e->msg));
178 
180  e->fd = mr->fd;
181  ar->index = region_index;
182  ar->size = mr->region_size;
183 
184  e->next = NULL;
185  if (c->msg_queue == NULL)
186  {
187  c->msg_queue = e;
188  return MEMIF_ERR_SUCCESS; /* 0 */
189  }
190 
191  memif_msg_queue_elt_t *cur = c->msg_queue;
192  while (cur->next != NULL)
193  {
194  cur = cur->next;
195  }
196  cur->next = e;
197 
198  return MEMIF_ERR_SUCCESS; /* 0 */
199 }
200 
201 /* send information about ring specified by direction (S2M | M2S) and index */
202 static_fn int
203 memif_msg_enq_add_ring (memif_connection_t * c, uint8_t index, uint8_t dir)
204 {
205  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
208  if (e == NULL)
209  return memif_syscall_error_handler (errno);
210 
211  memset (&e->msg, 0, sizeof (e->msg));
213 
215 
216  /* TODO: support multiple rings */
217  memif_queue_t *mq;
218  if (dir == MEMIF_RING_M2S)
219  mq = &c->rx_queues[index];
220  else
221  mq = &c->tx_queues[index];
222 
223  e->fd = mq->int_fd;
224  ar->index = index;
225  ar->offset = mq->offset;
226  ar->region = mq->region;
227  ar->log2_ring_size = mq->log2_ring_size;
228  ar->flags = (dir == MEMIF_RING_S2M) ? MEMIF_MSG_ADD_RING_FLAG_S2M : 0;
229  ar->private_hdr_size = 0;
230 
231  e->next = NULL;
232  if (c->msg_queue == NULL)
233  {
234  c->msg_queue = e;
235  return MEMIF_ERR_SUCCESS; /* 0 */
236  }
237 
238  memif_msg_queue_elt_t *cur = c->msg_queue;
239  while (cur->next != NULL)
240  {
241  cur = cur->next;
242  }
243  cur->next = e;
244 
245  return MEMIF_ERR_SUCCESS; /* 0 */
246 }
247 
248 /* used as connection request from slave */
249 static_fn int
251 {
252  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
255  if (e == NULL)
256  return memif_syscall_error_handler (errno);
257 
258  memset (&e->msg, 0, sizeof (e->msg));
260 
262  e->fd = -1;
263  strncpy ((char *) cm->if_name, (char *) c->args.interface_name,
264  strlen ((char *) c->args.interface_name));
265 
266  e->next = NULL;
267  if (c->msg_queue == NULL)
268  {
269  c->msg_queue = e;
270  return MEMIF_ERR_SUCCESS; /* 0 */
271  }
272 
273  memif_msg_queue_elt_t *cur = c->msg_queue;
274  while (cur->next != NULL)
275  {
276  cur = cur->next;
277  }
278  cur->next = e;
279 
280  return MEMIF_ERR_SUCCESS; /* 0 */
281 }
282 
283 /* used as confirmation of connection by master */
284 static_fn int
286 {
287  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
290  if (e == NULL)
291  return memif_syscall_error_handler (errno);
292 
293  memset (&e->msg, 0, sizeof (e->msg));
295 
297  e->fd = -1;
298  strncpy ((char *) cm->if_name, (char *) c->args.interface_name,
299  strlen ((char *) c->args.interface_name));
300 
301  e->next = NULL;
302  if (c->msg_queue == NULL)
303  {
304  c->msg_queue = e;
305  return MEMIF_ERR_SUCCESS; /* 0 */
306  }
307 
308  memif_msg_queue_elt_t *cur = c->msg_queue;
309  while (cur->next != NULL)
310  {
311  cur = cur->next;
312  }
313  cur->next = e;
314 
315  return MEMIF_ERR_SUCCESS; /* 0 */
316 }
317 
318 /* immediately send disconnect msg */
319  /* specifie protocol for disconnect msg err_code
320  so that it will be compatible with VPP? (header/doc) */
321 int
322 memif_msg_send_disconnect (int fd, uint8_t * err_string, uint32_t err_code)
323 {
324  memif_msg_t msg = { 0 };
326 
328  d->code = err_code;
329  uint16_t l = strlen ((char *) err_string);
330  if (l > 96)
331  {
332  DBG ("Disconnect string too long. Sending first 96 characters.");
333  l = 96;
334  }
335  strncpy ((char *) d->string, (char *) err_string, l);
336 
337  return memif_msg_send (fd, &msg, -1);
338 }
339 
340 static_fn int
342 {
343  memif_msg_hello_t *h = &msg->hello;
344 
345  if (msg->hello.min_version > MEMIF_VERSION ||
347  {
348  DBG ("incompatible protocol version");
349  return MEMIF_ERR_PROTO;
350  }
351 
352  c->run_args.num_s2m_rings = memif_min (h->max_s2m_ring + 1,
353  c->args.num_s2m_rings);
354  c->run_args.num_m2s_rings = memif_min (h->max_m2s_ring + 1,
355  c->args.num_m2s_rings);
356  c->run_args.log2_ring_size = memif_min (h->max_log2_ring_size,
357  c->args.log2_ring_size);
358  c->run_args.buffer_size = c->args.buffer_size;
359  strncpy ((char *) c->remote_name, (char *) h->name,
360  strlen ((char *) h->name));
361 
362  return MEMIF_ERR_SUCCESS; /* 0 */
363 }
364 
365 /* handle interface identification (id, secret (optional)) */
366 static_fn int
368 {
369  memif_msg_init_t *i = &msg->init;
370  memif_list_elt_t *elt = NULL;
371  memif_list_elt_t elt2;
372  memif_connection_t *c = NULL;
374  uint8_t err_string[96];
375  memset (err_string, 0, sizeof (char) * 96);
376  int err = MEMIF_ERR_SUCCESS; /* 0 */
377 
378  if (i->version != MEMIF_VERSION)
379  {
380  DBG ("MEMIF_VER_ERR");
381  strncpy ((char *) err_string, MEMIF_VER_ERR, strlen (MEMIF_VER_ERR));
382  err = MEMIF_ERR_PROTO;
383  goto error;
384  }
385 
386  get_list_elt (&elt, ms->interface_list, ms->interface_list_len, i->id);
387  if (elt == NULL)
388  {
389  DBG ("MEMIF_ID_ERR");
390  strncpy ((char *) err_string, MEMIF_ID_ERR, strlen (MEMIF_ID_ERR));
391  err = MEMIF_ERR_ID;
392  goto error;
393  }
394 
395  c = (memif_connection_t *) elt->data_struct;
396 
397  if (!(c->args.is_master))
398  {
399  DBG ("MEMIF_SLAVE_ERR");
400  strncpy ((char *) err_string, MEMIF_SLAVE_ERR,
401  strlen (MEMIF_SLAVE_ERR));
402  err = MEMIF_ERR_ACCSLAVE;
403  goto error;
404  }
405  if (c->fd != -1)
406  {
407  DBG ("MEMIF_CONN_ERR");
408  strncpy ((char *) err_string, MEMIF_CONN_ERR, strlen (MEMIF_CONN_ERR));
409  err = MEMIF_ERR_ALRCONN;
410  goto error;
411  }
412 
413  c->fd = fd;
414 
415  if (i->mode != c->args.mode)
416  {
417  DBG ("MEMIF_MODE_ERR");
418  strncpy ((char *) err_string, MEMIF_MODE_ERR, strlen (MEMIF_MODE_ERR));
419  err = MEMIF_ERR_MODE;
420  goto error;
421  }
422 
423  strncpy ((char *) c->remote_name, (char *) i->name,
424  strlen ((char *) i->name));
425 
426  if (strlen ((char *) c->args.secret) > 0)
427  {
428  int r;
429  if (strlen ((char *) i->secret) > 0)
430  {
431  if (strlen ((char *) c->args.secret) != strlen ((char *) i->secret))
432  {
433  DBG ("MEMIF_SECRET_ERR");
434  strncpy ((char *) err_string,
436  err = MEMIF_ERR_SECRET;
437  goto error;
438  }
439  r = strncmp ((char *) i->secret, (char *) c->args.secret,
440  strlen ((char *) c->args.secret));
441  if (r != 0)
442  {
443  DBG ("MEMIF_SECRET_ERR");
444  strncpy ((char *) err_string,
446  err = MEMIF_ERR_SECRET;
447  goto error;
448  }
449  }
450  else
451  {
452  DBG ("MEMIF_NOSECRET_ERR");
453  strncpy ((char *) err_string,
455  err = MEMIF_ERR_NOSECRET;
456  goto error;
457  }
458  }
459 
460  c->read_fn = memif_conn_fd_read_ready;
461  c->write_fn = memif_conn_fd_write_ready;
462  c->error_fn = memif_conn_fd_error;
463 
464  elt2.key = c->fd;
465  elt2.data_struct = c;
466 
467  add_list_elt (lm, &elt2, &lm->control_list, &lm->control_list_len);
469 
470  return err;
471 
472 error:
473  memif_msg_send_disconnect (fd, err_string, 0);
476  close (fd);
477  fd = -1;
478  return err;
479 }
480 
481 /* receive region information and add new region to connection (if possible) */
482 static_fn int
484  int fd)
485 {
486  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
487 
489  memif_region_t *mr;
490  if (fd < 0)
491  return MEMIF_ERR_NO_SHMFD;
492 
493  if (ar->index > MEMIF_MAX_REGION)
494  return MEMIF_ERR_MAXREG;
495 
496  mr =
497  (memif_region_t *) lm->realloc (c->regions,
498  sizeof (memif_region_t) *
499  (++c->regions_num));
500  if (mr == NULL)
501  return memif_syscall_error_handler (errno);
502  memset (mr + ar->index, 0, sizeof (memif_region_t));
503  c->regions = mr;
504  c->regions[ar->index].fd = fd;
505  c->regions[ar->index].region_size = ar->size;
506  c->regions[ar->index].addr = NULL;
507 
508  /* region 0 is never external */
509  if (lm->get_external_region_addr && (ar->index != 0))
510  c->regions[ar->index].is_external = 1;
511 
512  return MEMIF_ERR_SUCCESS; /* 0 */
513 }
514 
515 /* receive ring information and add new ring to connection queue
516  (based on direction S2M | M2S) */
517 static_fn int
519 {
520  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
521 
522  memif_msg_add_ring_t *ar = &msg->add_ring;
523 
524  memif_queue_t *mq;
525 
526  if (fd < 0)
527  return MEMIF_ERR_NO_INTFD;
528 
529  if (ar->private_hdr_size != 0)
530  return MEMIF_ERR_PRIVHDR;
531 
533  {
534  if (ar->index > MEMIF_MAX_S2M_RING)
535  return MEMIF_ERR_MAXRING;
536  if (ar->index >= c->args.num_s2m_rings)
537  return MEMIF_ERR_MAXRING;
538 
539  mq =
540  (memif_queue_t *) lm->realloc (c->rx_queues,
541  sizeof (memif_queue_t) *
542  (++c->rx_queues_num));
543  memset (mq + ar->index, 0, sizeof (memif_queue_t));
544  if (mq == NULL)
545  return memif_syscall_error_handler (errno);
546  c->rx_queues = mq;
547  c->rx_queues[ar->index].int_fd = fd;
548  c->rx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
549  c->rx_queues[ar->index].region = ar->region;
550  c->rx_queues[ar->index].offset = ar->offset;
551  c->run_args.num_s2m_rings++;
552  }
553  else
554  {
555  if (ar->index > MEMIF_MAX_M2S_RING)
556  return MEMIF_ERR_MAXRING;
557  if (ar->index >= c->args.num_m2s_rings)
558  return MEMIF_ERR_MAXRING;
559 
560  mq =
561  (memif_queue_t *) lm->realloc (c->tx_queues,
562  sizeof (memif_queue_t) *
563  (++c->tx_queues_num));
564  memset (mq + ar->index, 0, sizeof (memif_queue_t));
565  if (mq == NULL)
566  return memif_syscall_error_handler (errno);
567  c->tx_queues = mq;
568  c->tx_queues[ar->index].int_fd = fd;
569  c->tx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
570  c->tx_queues[ar->index].region = ar->region;
571  c->tx_queues[ar->index].offset = ar->offset;
572  c->run_args.num_m2s_rings++;
573  }
574 
575  return MEMIF_ERR_SUCCESS; /* 0 */
576 }
577 
578 /* slave -> master */
579 static_fn int
581 {
582  memif_msg_connect_t *cm = &msg->connect;
583  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
584  memif_list_elt_t elt;
585 
586  int err;
587  err = memif_connect1 (c);
588  if (err != MEMIF_ERR_SUCCESS)
589  return err;
590 
591  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
592  strlen ((char *) cm->if_name));
593 
594  int i;
595  if (c->on_interrupt != NULL)
596  {
597  for (i = 0; i < c->run_args.num_m2s_rings; i++)
598  {
599  elt.key = c->rx_queues[i].int_fd;
600  elt.data_struct = c;
601  add_list_elt (lm, &elt, &lm->interrupt_list,
602  &lm->interrupt_list_len);
603 
604  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ,
605  lm->private_ctx);
606  }
607 
608  }
609 
610  c->on_connect ((void *) c, c->private_ctx);
611 
612  return err;
613 }
614 
615 /* master -> slave */
616 static_fn int
618 {
619  memif_msg_connect_t *cm = &msg->connect;
620  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
621 
622  int err;
623  err = memif_connect1 (c);
624  if (err != MEMIF_ERR_SUCCESS)
625  return err;
626 
627  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
628  strlen ((char *) cm->if_name));
629 
630  int i;
631  if (c->on_interrupt != NULL)
632  {
633  for (i = 0; i < c->run_args.num_s2m_rings; i++)
634  {
635  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ,
636  lm->private_ctx);
637  }
638  }
639 
640  c->on_connect ((void *) c, c->private_ctx);
641 
642  return err;
643 }
644 
645 static_fn int
647 {
649 
650  memset (c->remote_disconnect_string, 0,
651  sizeof (c->remote_disconnect_string));
652  strncpy ((char *) c->remote_disconnect_string, (char *) d->string,
653  strlen ((char *) d->string));
654 
655  /* on returning error, handle function will call memif_disconnect () */
656  DBG ("disconnect received: %s, mode: %d",
657  c->remote_disconnect_string, c->args.mode);
658  return MEMIF_ERR_DISCONNECT;
659 }
660 
661 static_fn int
663 {
664  char ctl[CMSG_SPACE (sizeof (int)) +
665  CMSG_SPACE (sizeof (struct ucred))] = { 0 };
666  struct msghdr mh = { 0 };
667  struct iovec iov[1];
668  memif_msg_t msg = { 0 };
669  ssize_t size;
670  int err = MEMIF_ERR_SUCCESS; /* 0 */
671  int fd = -1;
672  int i;
673  memif_connection_t *c = NULL;
674  memif_socket_t *ms = NULL;
675  memif_list_elt_t *elt = NULL;
676 
677  iov[0].iov_base = (void *) &msg;
678  iov[0].iov_len = sizeof (memif_msg_t);
679  mh.msg_iov = iov;
680  mh.msg_iovlen = 1;
681  mh.msg_control = ctl;
682  mh.msg_controllen = sizeof (ctl);
683 
684  DBG ("recvmsg fd %d", ifd);
685  size = recvmsg (ifd, &mh, 0);
686  if (size != sizeof (memif_msg_t))
687  {
688  if (size == 0)
689  return MEMIF_ERR_DISCONNECTED;
690  else
691  return MEMIF_ERR_MFMSG;
692  }
693 
694  struct cmsghdr *cmsg;
695 
696  cmsg = CMSG_FIRSTHDR (&mh);
697  while (cmsg)
698  {
699  if (cmsg->cmsg_level == SOL_SOCKET)
700  {
701  if (cmsg->cmsg_type == SCM_CREDENTIALS)
702  {
703  /* Do nothing */ ;
704  }
705  else if (cmsg->cmsg_type == SCM_RIGHTS)
706  {
707  int *fdp = (int *) CMSG_DATA (cmsg);
708  fd = *fdp;
709  }
710  }
711  cmsg = CMSG_NXTHDR (&mh, cmsg);
712  }
713 
714  DBG ("Message type %u received", msg.type);
715 
716  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
717  if (elt != NULL)
718  c = (memif_connection_t *) elt->data_struct;
719 
720  switch (msg.type)
721  {
722  case MEMIF_MSG_TYPE_ACK:
723  break;
724 
726  if ((err = memif_msg_receive_hello (c, &msg)) != MEMIF_ERR_SUCCESS)
727  return err;
729  return err;
730  if ((err = memif_msg_enq_init (c)) != MEMIF_ERR_SUCCESS)
731  return err;
732  for (i = 0; i < c->regions_num; i++)
733  {
734  if ((err = memif_msg_enq_add_region (c, i)) != MEMIF_ERR_SUCCESS)
735  return err;
736  }
737  for (i = 0; i < c->run_args.num_s2m_rings; i++)
738  {
739  if ((err =
742  return err;
743  }
744  for (i = 0; i < c->run_args.num_m2s_rings; i++)
745  {
746  if ((err =
749  return err;
750  }
751  if ((err = memif_msg_enq_connect (c)) != MEMIF_ERR_SUCCESS)
752  return err;
753  break;
754 
755  case MEMIF_MSG_TYPE_INIT:
756  get_list_elt (&elt, lm->pending_list, lm->pending_list_len, ifd);
757  if (elt == NULL)
758  return -1;
759  ms = (memif_socket_t *) elt->data_struct;
760  if ((err = memif_msg_receive_init (ms, ifd, &msg)) != MEMIF_ERR_SUCCESS)
761  return err;
762  /* c->remote_pid = cr->pid */
763  /* c->remote_uid = cr->uid */
764  /* c->remote_gid = cr->gid */
765  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
766  if (elt == NULL)
767  return -1;
768  c = (memif_connection_t *) elt->data_struct;
769  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
770  return err;
771  break;
772 
774  if ((err =
776  return err;
777  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
778  return err;
779  break;
780 
782  if ((err =
784  return err;
785  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
786  return err;
787  break;
788 
790  if ((err = memif_msg_receive_connect (c, &msg)) != MEMIF_ERR_SUCCESS)
791  return err;
792  if ((err = memif_msg_enq_connected (c)) != MEMIF_ERR_SUCCESS)
793  return err;
794  break;
795 
797  if ((err = memif_msg_receive_connected (c, &msg)) != MEMIF_ERR_SUCCESS)
798  return err;
799  break;
800 
802  if ((err = memif_msg_receive_disconnect (c, &msg)) != MEMIF_ERR_SUCCESS)
803  return err;
804  break;
805 
806  default:
807  return MEMIF_ERR_UNKNOWN_MSG;;
808  break;
809  }
810 
811  if (c != NULL)
812  c->flags |= MEMIF_CONNECTION_FLAG_WRITE;
813 
814  return MEMIF_ERR_SUCCESS; /* 0 */
815 }
816 
817 int
819 {
820  DBG ("connection fd error");
821  strncpy ((char *) c->remote_disconnect_string, "connection fd error", 19);
822  int err = memif_disconnect_internal (c);
823  return err;
824 }
825 
826 /* calls memif_msg_receive to handle pending messages on socket */
827 int
829 {
830  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
831  int err;
832 
833  err = memif_msg_receive (lm, c->fd);
834  if (err != 0)
835  {
836  err = memif_disconnect_internal (c);
837  }
838  return err;
839 }
840 
841 /* get msg from msg queue buffer and send it to socket */
842 int
844 {
845  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
846  int err = MEMIF_ERR_SUCCESS; /* 0 */
847 
848 
849  if ((c->flags & MEMIF_CONNECTION_FLAG_WRITE) == 0)
850  goto done;
851 
852  memif_msg_queue_elt_t *e = c->msg_queue;
853  if (e == NULL)
854  goto done;
855 
856  c->msg_queue = c->msg_queue->next;
857 
858  c->flags &= ~MEMIF_CONNECTION_FLAG_WRITE;
859 
860  err = memif_msg_send (c->fd, &e->msg, e->fd);
861  lm->free (e);
862  goto done;
863 
864 done:
865  return err;
866 }
867 
868 int
870 {
871  int addr_len;
872  struct sockaddr_un client;
873  int conn_fd;
875 
876  DBG ("accept called");
877 
878  addr_len = sizeof (client);
879  conn_fd =
880  accept (ms->fd, (struct sockaddr *) &client, (socklen_t *) & addr_len);
881 
882  if (conn_fd < 0)
883  {
884  return memif_syscall_error_handler (errno);
885  }
886  DBG ("accept fd %d", ms->fd);
887  DBG ("conn fd %d", conn_fd);
888 
889  memif_list_elt_t elt;
890  elt.key = conn_fd;
891  elt.data_struct = ms;
892 
893  add_list_elt (lm, &elt, &lm->pending_list, &lm->pending_list_len);
895  lm->private_ctx);
896 
897  return memif_msg_send_hello (lm, conn_fd);
898 }
899 
900 int
902 {
903  int err;
904 
905  err = memif_msg_receive (lm, fd);
906 
907  return err;
908 }
static_fn int memif_msg_receive_disconnect(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:646
memif_version_t max_version
Definition: memif.h:78
memif_interface_mode_t mode
Definition: memif.h:89
int memif_conn_fd_write_ready(memif_connection_t *c)
Definition: socket.c:843
clib_error_t * memif_conn_fd_accept_ready(clib_file_t *uf)
Definition: socket.c:657
memif_msg_add_region_t add_region
Definition: memif.h:134
#define MEMIF_FD_EVENT_READ
user needs to set events that occured on fd and pass them to memif_control_fd_handler ...
Definition: libmemif.h:89
#define MEMIF_SECRET_ERR
Definition: socket.h:29
Optimized string handling code, including c11-compliant "safe C library" variants.
uint8_t string[96]
Definition: memif.h:124
memif_alloc_t * alloc
#define MEMIF_SLAVE_ERR
Definition: socket.h:26
memif_msg_add_ring_t add_ring
Definition: memif.h:135
uint8_t app_name[MEMIF_NAME_LEN]
#define MEMIF_MSG_ADD_RING_FLAG_S2M
Definition: memif.h:103
#define MEMIF_MAX_REGION
Definition: private.h:29
int memif_conn_fd_read_ready(memif_connection_t *c)
Definition: socket.c:828
static_fn int memif_msg_send(int fd, memif_msg_t *msg, int afd)
Definition: socket.c:39
int memif_disconnect_internal(memif_connection_t *c)
Definition: main.c:1665
#define MEMIF_CONNECTION_FLAG_WRITE
memif_region_index_t region
Definition: memif.h:105
memif_version_t min_version
Definition: memif.h:77
uint16_t private_hdr_size
Definition: memif.h:108
memif_list_elt_t * interface_list
memif_interface_id_t id
Definition: memif.h:88
uint8_t name[32]
Definition: memif.h:76
#define static_fn
Definition: socket.h:86
libmemif_main_t * get_libmemif_main(memif_socket_t *ms)
Definition: main.c:239
memif_ring_index_t max_m2s_ring
Definition: memif.h:80
clib_error_t * memif_init_regions_and_queues(memif_if_t *mif)
Definition: memif.c:344
#define MEMIF_ID_ERR
Definition: socket.h:25
#define MEMIF_NOSECRET_ERR
Definition: socket.h:30
memif_region_offset_t offset
Definition: private.h:121
#define MEMIF_MAX_M2S_RING
Definition: private.h:27
memif_region_offset_t offset
Definition: memif.h:106
static_fn int memif_msg_receive_connect(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:580
#define MEMIF_MAX_LOG2_RING_SIZE
Definition: private.h:30
static_fn int memif_msg_receive_init(memif_socket_t *ms, int fd, memif_msg_t *msg)
Definition: socket.c:367
memif_msg_init_t init
Definition: memif.h:133
int memif_syscall_error_handler(int err_code)
Definition: main.c:202
memif_ring_index_t index
Definition: memif.h:104
clib_error_t * memif_msg_send_disconnect(memif_if_t *mif, clib_error_t *err)
Definition: socket.c:198
vnet_crypto_main_t * cm
Definition: quic_crypto.c:53
#define MEMIF_CONN_ERR
Definition: socket.h:27
static_fn int memif_msg_enq_connected(memif_connection_t *c)
Definition: socket.c:285
static_fn int memif_msg_enq_init(memif_connection_t *c)
Definition: socket.c:124
memif_list_elt_t * pending_list
#define MEMIF_FD_EVENT_DEL
if set, informs that fd is going to be closed (user may want to stop watching for events on this fd) ...
Definition: libmemif.h:94
memif_msg_disconnect_t disconnect
Definition: memif.h:138
struct memif_msg_queue_elt * next
u64 size
Definition: vhost_user.h:150
vec_header_t h
Definition: buffer.c:322
static_fn int memif_msg_enq_ack(memif_connection_t *c)
Definition: socket.c:72
memif_list_elt_t * interrupt_list
uint16_t pending_list_len
memif_msg_hello_t hello
Definition: memif.h:132
memif_log2_ring_size_t max_log2_ring_size
Definition: memif.h:82
int memif_read_ready(libmemif_main_t *lm, int fd)
Definition: socket.c:901
uint8_t if_name[32]
Definition: memif.h:113
uint8_t name[32]
Definition: memif.h:91
svmdb_client_t * c
uint8_t if_name[32]
Definition: memif.h:118
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
int get_list_elt(memif_list_elt_t **e, memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:366
#define MEMIF_MODE_ERR
Definition: socket.h:28
memif_list_elt_t * control_list
#define DBG(...)
memif_region_index_t index
Definition: memif.h:96
memif_free_t * free
uint16_t interrupt_list_len
uint16_t control_list_len
memif_log2_ring_size_t log2_ring_size
Definition: memif.h:107
memif_version_t version
Definition: memif.h:87
memif_realloc_t * realloc
#define memif_min(a, b)
Definition: memif_private.h:54
memif_ring_index_t max_s2m_ring
Definition: memif.h:81
static_fn int memif_msg_enq_add_region(memif_connection_t *c, uint8_t region_index)
Definition: socket.c:166
memif_msg_connect_t connect
Definition: memif.h:136
#define MEMIF_VERSION
Definition: memif.h:28
static_fn int memif_msg_receive_add_ring(memif_connection_t *c, memif_msg_t *msg, int fd)
Definition: socket.c:518
memif_get_external_region_addr_t * get_external_region_addr
uint8_t secret[MEMIF_SECRET_SIZE]
Definition: memif.h:90
uint16_t flags
Definition: memif.h:102
static_fn int memif_msg_receive_add_region(memif_connection_t *c, memif_msg_t *msg, int fd)
Definition: socket.c:483
#define MEMIF_MAX_S2M_RING
Definition: private.h:28
static_fn int memif_msg_receive(libmemif_main_t *lm, int ifd)
Definition: socket.c:662
memif_region_size_t size
Definition: memif.h:97
memif_region_index_t max_region
Definition: memif.h:79
memif_msg_type_t type
Definition: memif.h:129
static_fn int memif_msg_enq_connect(memif_connection_t *c)
Definition: socket.c:250
memif_log2_ring_size_t log2_ring_size
Definition: private.h:119
static_fn int memif_msg_receive_hello(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:341
memif_msg_connected_t connected
Definition: memif.h:137
memif_control_fd_update_t * control_fd_update
static_fn int memif_msg_send_hello(libmemif_main_t *lm, int fd)
Definition: socket.c:102
#define MEMIF_VER_ERR
Definition: socket.h:24
static_fn int memif_msg_receive_connected(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:617
int memif_conn_fd_error(memif_connection_t *c)
Definition: socket.c:818
int memif_connect1(memif_connection_t *c)
Definition: main.c:1880
int free_list_elt(memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:390
#define MEMIF_FD_EVENT_WRITE
Definition: libmemif.h:90
void * private_ctx
int add_list_elt(libmemif_main_t *lm, memif_list_elt_t *e, memif_list_elt_t **list, uint16_t *len)
Definition: main.c:330
memif_region_index_t region
Definition: private.h:120
static_fn int memif_msg_enq_add_ring(memif_connection_t *c, uint8_t index, uint8_t dir)
Definition: socket.c:203
uint16_t interface_list_len
memif_region_size_t region_size
Definition: private.h:103