FD.io VPP  v21.06-1-gbb7418cf9
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  strlcpy ((char *) h->name, (char *) lm->app_name, sizeof (h->name));
115 
116  /* msg hello is not enqueued but sent directly,
117  because it is the first msg to be sent */
118  return memif_msg_send (fd, &msg, -1);
119 }
120 
121 /* send id and secret (optional) for interface identification */
122 static_fn int
124 {
125  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
128  if (e == NULL)
129  return memif_syscall_error_handler (errno);
130  memset (e, 0, sizeof (memif_msg_queue_elt_t));
131 
132  memset (&e->msg, 0, sizeof (e->msg));
133  memif_msg_init_t *i = &e->msg.init;
134 
136  e->fd = -1;
137  i->version = MEMIF_VERSION;
138  i->id = c->args.interface_id;
139  i->mode = c->args.mode;
140 
141  strlcpy ((char *) i->name, (char *) lm->app_name, sizeof (i->name));
142  if (strlen ((char *) c->args.secret) > 0)
143  strncpy ((char *) i->secret, (char *) c->args.secret, sizeof (i->secret));
144 
145  e->next = NULL;
146  if (c->msg_queue == NULL)
147  {
148  c->msg_queue = e;
149  return MEMIF_ERR_SUCCESS; /* 0 */
150  }
151 
152  memif_msg_queue_elt_t *cur = c->msg_queue;
153  while (cur->next != NULL)
154  {
155  cur = cur->next;
156  }
157  cur->next = e;
158 
159  return MEMIF_ERR_SUCCESS; /* 0 */
160 }
161 
162 /* send information about region specified by region_index */
163 static_fn int
165 {
166  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
167  memif_region_t *mr = &c->regions[region_index];
168 
171  if (e == NULL)
172  return memif_syscall_error_handler (errno);
173 
174  memset (&e->msg, 0, sizeof (e->msg));
176 
178  e->fd = mr->fd;
179  ar->index = region_index;
180  ar->size = mr->region_size;
181 
182  e->next = NULL;
183  if (c->msg_queue == NULL)
184  {
185  c->msg_queue = e;
186  return MEMIF_ERR_SUCCESS; /* 0 */
187  }
188 
189  memif_msg_queue_elt_t *cur = c->msg_queue;
190  while (cur->next != NULL)
191  {
192  cur = cur->next;
193  }
194  cur->next = e;
195 
196  return MEMIF_ERR_SUCCESS; /* 0 */
197 }
198 
199 /* send information about ring specified by direction (S2M | M2S) and index */
200 static_fn int
202 {
203  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
206  if (e == NULL)
207  return memif_syscall_error_handler (errno);
208 
209  memset (&e->msg, 0, sizeof (e->msg));
211 
213 
214  /* TODO: support multiple rings */
215  memif_queue_t *mq;
216  if (dir == MEMIF_RING_M2S)
217  mq = &c->rx_queues[index];
218  else
219  mq = &c->tx_queues[index];
220 
221  e->fd = mq->int_fd;
222  ar->index = index;
223  ar->offset = mq->offset;
224  ar->region = mq->region;
225  ar->log2_ring_size = mq->log2_ring_size;
226  ar->flags = (dir == MEMIF_RING_S2M) ? MEMIF_MSG_ADD_RING_FLAG_S2M : 0;
227  ar->private_hdr_size = 0;
228 
229  e->next = NULL;
230  if (c->msg_queue == NULL)
231  {
232  c->msg_queue = e;
233  return MEMIF_ERR_SUCCESS; /* 0 */
234  }
235 
236  memif_msg_queue_elt_t *cur = c->msg_queue;
237  while (cur->next != NULL)
238  {
239  cur = cur->next;
240  }
241  cur->next = e;
242 
243  return MEMIF_ERR_SUCCESS; /* 0 */
244 }
245 
246 /* used as connection request from slave */
247 static_fn int
249 {
250  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
253  if (e == NULL)
254  return memif_syscall_error_handler (errno);
255 
256  memset (&e->msg, 0, sizeof (e->msg));
258 
260  e->fd = -1;
261  strlcpy ((char *) cm->if_name, (char *) c->args.interface_name,
262  sizeof (cm->if_name));
263 
264  e->next = NULL;
265  if (c->msg_queue == NULL)
266  {
267  c->msg_queue = e;
268  return MEMIF_ERR_SUCCESS; /* 0 */
269  }
270 
271  memif_msg_queue_elt_t *cur = c->msg_queue;
272  while (cur->next != NULL)
273  {
274  cur = cur->next;
275  }
276  cur->next = e;
277 
278  return MEMIF_ERR_SUCCESS; /* 0 */
279 }
280 
281 /* used as confirmation of connection by master */
282 static_fn int
284 {
285  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
288  if (e == NULL)
289  return memif_syscall_error_handler (errno);
290 
291  memset (&e->msg, 0, sizeof (e->msg));
293 
295  e->fd = -1;
296  strlcpy ((char *) cm->if_name, (char *) c->args.interface_name,
297  sizeof (cm->if_name));
298 
299  e->next = NULL;
300  if (c->msg_queue == NULL)
301  {
302  c->msg_queue = e;
303  return MEMIF_ERR_SUCCESS; /* 0 */
304  }
305 
306  memif_msg_queue_elt_t *cur = c->msg_queue;
307  while (cur->next != NULL)
308  {
309  cur = cur->next;
310  }
311  cur->next = e;
312 
313  return MEMIF_ERR_SUCCESS; /* 0 */
314 }
315 
316 /* immediately send disconnect msg */
317  /* specify protocol for disconnect msg err_code
318  so that it will be compatible with VPP? (header/doc) */
319 int
320 memif_msg_send_disconnect (int fd, uint8_t * err_string, uint32_t err_code)
321 {
322  memif_msg_t msg = { 0 };
324 
326  d->code = err_code;
327  uint16_t l = strlen ((char *) err_string);
328  if (l > sizeof (d->string) - 1)
329  {
330  DBG ("Disconnect string too long. Sending the first %d characters.",
331  sizeof (d->string) - 1);
332  }
333  strlcpy ((char *) d->string, (char *) err_string, sizeof (d->string));
334 
335  return memif_msg_send (fd, &msg, -1);
336 }
337 
338 static_fn int
340 {
341  memif_msg_hello_t *h = &msg->hello;
342 
343  if (msg->hello.min_version > MEMIF_VERSION ||
345  {
346  DBG ("incompatible protocol version");
347  return MEMIF_ERR_PROTO;
348  }
349 
350  c->run_args.num_s2m_rings = memif_min (h->max_s2m_ring + 1,
351  c->args.num_s2m_rings);
352  c->run_args.num_m2s_rings = memif_min (h->max_m2s_ring + 1,
353  c->args.num_m2s_rings);
354  c->run_args.log2_ring_size = memif_min (h->max_log2_ring_size,
355  c->args.log2_ring_size);
356  c->run_args.buffer_size = c->args.buffer_size;
357  strlcpy ((char *) c->remote_name, (char *) h->name, sizeof (c->remote_name));
358 
359  return MEMIF_ERR_SUCCESS; /* 0 */
360 }
361 
362 /* handle interface identification (id, secret (optional)) */
363 static_fn int
365 {
366  memif_msg_init_t *i = &msg->init;
367  memif_list_elt_t *elt = NULL;
368  memif_list_elt_t elt2;
369  memif_connection_t *c = NULL;
371  uint8_t err_string[96];
372  memset (err_string, 0, sizeof (char) * 96);
373  int err = MEMIF_ERR_SUCCESS; /* 0 */
374 
375  if (i->version != MEMIF_VERSION)
376  {
377  DBG ("MEMIF_VER_ERR");
378  strncpy ((char *) err_string, MEMIF_VER_ERR, strlen (MEMIF_VER_ERR));
379  err = MEMIF_ERR_PROTO;
380  goto error;
381  }
382 
383  get_list_elt (&elt, ms->interface_list, ms->interface_list_len, i->id);
384  if (elt == NULL)
385  {
386  DBG ("MEMIF_ID_ERR");
387  strncpy ((char *) err_string, MEMIF_ID_ERR, strlen (MEMIF_ID_ERR));
388  err = MEMIF_ERR_ID;
389  goto error;
390  }
391 
392  c = (memif_connection_t *) elt->data_struct;
393 
394  if (!(c->args.is_master))
395  {
396  DBG ("MEMIF_SLAVE_ERR");
397  strncpy ((char *) err_string, MEMIF_SLAVE_ERR,
398  strlen (MEMIF_SLAVE_ERR));
399  err = MEMIF_ERR_ACCSLAVE;
400  goto error;
401  }
402  if (c->fd != -1)
403  {
404  DBG ("MEMIF_CONN_ERR");
405  strncpy ((char *) err_string, MEMIF_CONN_ERR, strlen (MEMIF_CONN_ERR));
406  err = MEMIF_ERR_ALRCONN;
407  goto error;
408  }
409 
410  c->fd = fd;
411 
412  if (i->mode != c->args.mode)
413  {
414  DBG ("MEMIF_MODE_ERR");
415  strncpy ((char *) err_string, MEMIF_MODE_ERR, strlen (MEMIF_MODE_ERR));
416  err = MEMIF_ERR_MODE;
417  goto error;
418  }
419 
420  strlcpy ((char *) c->remote_name, (char *) i->name, sizeof (c->remote_name));
421 
422  if (strlen ((char *) c->args.secret) > 0)
423  {
424  int r;
425  if (strlen ((char *) i->secret) > 0)
426  {
427  if (strlen ((char *) c->args.secret) != strlen ((char *) i->secret))
428  {
429  DBG ("MEMIF_SECRET_ERR");
430  strncpy ((char *) err_string,
432  err = MEMIF_ERR_SECRET;
433  goto error;
434  }
435  r = strncmp ((char *) i->secret, (char *) c->args.secret,
436  strlen ((char *) c->args.secret));
437  if (r != 0)
438  {
439  DBG ("MEMIF_SECRET_ERR");
440  strncpy ((char *) err_string,
442  err = MEMIF_ERR_SECRET;
443  goto error;
444  }
445  }
446  else
447  {
448  DBG ("MEMIF_NOSECRET_ERR");
449  strncpy ((char *) err_string,
451  err = MEMIF_ERR_NOSECRET;
452  goto error;
453  }
454  }
455 
456  c->read_fn = memif_conn_fd_read_ready;
457  c->write_fn = memif_conn_fd_write_ready;
458  c->error_fn = memif_conn_fd_error;
459 
460  elt2.key = c->fd;
461  elt2.data_struct = c;
462 
463  add_list_elt (lm, &elt2, &lm->control_list, &lm->control_list_len);
465 
466  return err;
467 
468 error:
469  memif_msg_send_disconnect (fd, err_string, 0);
472  close (fd);
473  fd = -1;
474  return err;
475 }
476 
477 /* receive region information and add new region to connection (if possible) */
478 static_fn int
480  int fd)
481 {
482  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
483 
485  memif_region_t *mr;
486  if (fd < 0)
487  return MEMIF_ERR_NO_SHMFD;
488 
489  if (ar->index > MEMIF_MAX_REGION)
490  return MEMIF_ERR_MAXREG;
491 
492  mr =
493  (memif_region_t *) lm->realloc (c->regions,
494  sizeof (memif_region_t) *
495  (++c->regions_num));
496  if (mr == NULL)
497  return memif_syscall_error_handler (errno);
498  memset (mr + ar->index, 0, sizeof (memif_region_t));
499  c->regions = mr;
500  c->regions[ar->index].fd = fd;
501  c->regions[ar->index].region_size = ar->size;
502  c->regions[ar->index].addr = NULL;
503 
504  /* region 0 is never external */
505  if (lm->get_external_region_addr && (ar->index != 0))
506  c->regions[ar->index].is_external = 1;
507 
508  return MEMIF_ERR_SUCCESS; /* 0 */
509 }
510 
511 /* receive ring information and add new ring to connection queue
512  (based on direction S2M | M2S) */
513 static_fn int
515 {
516  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
517 
518  memif_msg_add_ring_t *ar = &msg->add_ring;
519 
520  memif_queue_t *mq;
521 
522  if (fd < 0)
523  return MEMIF_ERR_NO_INTFD;
524 
525  if (ar->private_hdr_size != 0)
526  return MEMIF_ERR_PRIVHDR;
527 
529  {
530  if (ar->index > MEMIF_MAX_S2M_RING)
531  return MEMIF_ERR_MAXRING;
532  if (ar->index >= c->args.num_s2m_rings)
533  return MEMIF_ERR_MAXRING;
534 
535  mq =
536  (memif_queue_t *) lm->realloc (c->rx_queues,
537  sizeof (memif_queue_t) *
538  (++c->rx_queues_num));
539  memset (mq + ar->index, 0, sizeof (memif_queue_t));
540  if (mq == NULL)
541  return memif_syscall_error_handler (errno);
542  c->rx_queues = mq;
543  c->rx_queues[ar->index].int_fd = fd;
544  c->rx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
545  c->rx_queues[ar->index].region = ar->region;
546  c->rx_queues[ar->index].offset = ar->offset;
547  c->run_args.num_s2m_rings++;
548  }
549  else
550  {
551  if (ar->index > MEMIF_MAX_M2S_RING)
552  return MEMIF_ERR_MAXRING;
553  if (ar->index >= c->args.num_m2s_rings)
554  return MEMIF_ERR_MAXRING;
555 
556  mq =
557  (memif_queue_t *) lm->realloc (c->tx_queues,
558  sizeof (memif_queue_t) *
559  (++c->tx_queues_num));
560  memset (mq + ar->index, 0, sizeof (memif_queue_t));
561  if (mq == NULL)
562  return memif_syscall_error_handler (errno);
563  c->tx_queues = mq;
564  c->tx_queues[ar->index].int_fd = fd;
565  c->tx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
566  c->tx_queues[ar->index].region = ar->region;
567  c->tx_queues[ar->index].offset = ar->offset;
568  c->run_args.num_m2s_rings++;
569  }
570 
571  return MEMIF_ERR_SUCCESS; /* 0 */
572 }
573 
574 /* slave -> master */
575 static_fn int
577 {
578  memif_msg_connect_t *cm = &msg->connect;
579  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
581 
582  int err;
583  err = memif_connect1 (c);
584  if (err != MEMIF_ERR_SUCCESS)
585  return err;
586 
587  strlcpy ((char *) c->remote_if_name, (char *) cm->if_name,
588  sizeof (c->remote_if_name));
589 
590  int i;
591  if (c->on_interrupt != NULL)
592  {
593  for (i = 0; i < c->run_args.num_m2s_rings; i++)
594  {
595  elt.key = c->rx_queues[i].int_fd;
596  elt.data_struct = c;
597  add_list_elt (lm, &elt, &lm->interrupt_list,
598  &lm->interrupt_list_len);
599 
600  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ,
601  lm->private_ctx);
602  }
603 
604  }
605 
606  c->on_connect ((void *) c, c->private_ctx);
607 
608  return err;
609 }
610 
611 /* master -> slave */
612 static_fn int
614 {
615  memif_msg_connect_t *cm = &msg->connect;
616  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
617 
618  int err;
619  err = memif_connect1 (c);
620  if (err != MEMIF_ERR_SUCCESS)
621  return err;
622 
623  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
624  sizeof (c->remote_if_name));
625 
626  int i;
627  if (c->on_interrupt != NULL)
628  {
629  for (i = 0; i < c->run_args.num_s2m_rings; i++)
630  {
631  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ,
632  lm->private_ctx);
633  }
634  }
635 
636  c->on_connect ((void *) c, c->private_ctx);
637 
638  return err;
639 }
640 
641 static_fn int
643 {
645 
646  memset (c->remote_disconnect_string, 0,
647  sizeof (c->remote_disconnect_string));
648  strncpy ((char *) c->remote_disconnect_string, (char *) d->string,
649  sizeof (c->remote_disconnect_string));
650 
651  /* on returning error, handle function will call memif_disconnect () */
652  DBG ("disconnect received: %s, mode: %d",
653  c->remote_disconnect_string, c->args.mode);
654  return MEMIF_ERR_DISCONNECT;
655 }
656 
657 static_fn int
659 {
660  char ctl[CMSG_SPACE (sizeof (int)) +
661  CMSG_SPACE (sizeof (struct ucred))] = { 0 };
662  struct msghdr mh = { 0 };
663  struct iovec iov[1];
664  memif_msg_t msg = { 0 };
665  ssize_t size;
666  int err = MEMIF_ERR_SUCCESS; /* 0 */
667  int fd = -1;
668  int i;
669  memif_connection_t *c = NULL;
670  memif_socket_t *ms = NULL;
671  memif_list_elt_t *elt = NULL;
672 
673  iov[0].iov_base = (void *) &msg;
674  iov[0].iov_len = sizeof (memif_msg_t);
675  mh.msg_iov = iov;
676  mh.msg_iovlen = 1;
677  mh.msg_control = ctl;
678  mh.msg_controllen = sizeof (ctl);
679 
680  DBG ("recvmsg fd %d", ifd);
681  size = recvmsg (ifd, &mh, 0);
682  if (size != sizeof (memif_msg_t))
683  {
684  if (size == 0)
685  return MEMIF_ERR_DISCONNECTED;
686  else
687  return MEMIF_ERR_MFMSG;
688  }
689 
690  struct cmsghdr *cmsg;
691 
692  cmsg = CMSG_FIRSTHDR (&mh);
693  while (cmsg)
694  {
695  if (cmsg->cmsg_level == SOL_SOCKET)
696  {
697  if (cmsg->cmsg_type == SCM_CREDENTIALS)
698  {
699  /* Do nothing */ ;
700  }
701  else if (cmsg->cmsg_type == SCM_RIGHTS)
702  {
703  int *fdp = (int *) CMSG_DATA (cmsg);
704  fd = *fdp;
705  }
706  }
707  cmsg = CMSG_NXTHDR (&mh, cmsg);
708  }
709 
710  DBG ("Message type %u received", msg.type);
711 
712  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
713  if (elt != NULL)
714  c = (memif_connection_t *) elt->data_struct;
715 
716  switch (msg.type)
717  {
718  case MEMIF_MSG_TYPE_ACK:
719  break;
720 
722  if ((err = memif_msg_receive_hello (c, &msg)) != MEMIF_ERR_SUCCESS)
723  return err;
725  return err;
726  if ((err = memif_msg_enq_init (c)) != MEMIF_ERR_SUCCESS)
727  return err;
728  for (i = 0; i < c->regions_num; i++)
729  {
730  if ((err = memif_msg_enq_add_region (c, i)) != MEMIF_ERR_SUCCESS)
731  return err;
732  }
733  for (i = 0; i < c->run_args.num_s2m_rings; i++)
734  {
735  if ((err =
738  return err;
739  }
740  for (i = 0; i < c->run_args.num_m2s_rings; i++)
741  {
742  if ((err =
745  return err;
746  }
747  if ((err = memif_msg_enq_connect (c)) != MEMIF_ERR_SUCCESS)
748  return err;
749  break;
750 
751  case MEMIF_MSG_TYPE_INIT:
752  get_list_elt (&elt, lm->pending_list, lm->pending_list_len, ifd);
753  if (elt == NULL)
754  return -1;
755  ms = (memif_socket_t *) elt->data_struct;
756  if ((err = memif_msg_receive_init (ms, ifd, &msg)) != MEMIF_ERR_SUCCESS)
757  return err;
758  /* c->remote_pid = cr->pid */
759  /* c->remote_uid = cr->uid */
760  /* c->remote_gid = cr->gid */
761  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
762  if (elt == NULL)
763  return -1;
764  c = (memif_connection_t *) elt->data_struct;
765  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
766  return err;
767  break;
768 
770  if ((err =
772  return err;
773  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
774  return err;
775  break;
776 
778  if ((err =
780  return err;
781  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
782  return err;
783  break;
784 
786  if ((err = memif_msg_receive_connect (c, &msg)) != MEMIF_ERR_SUCCESS)
787  return err;
788  if ((err = memif_msg_enq_connected (c)) != MEMIF_ERR_SUCCESS)
789  return err;
790  break;
791 
793  if ((err = memif_msg_receive_connected (c, &msg)) != MEMIF_ERR_SUCCESS)
794  return err;
795  break;
796 
798  if ((err = memif_msg_receive_disconnect (c, &msg)) != MEMIF_ERR_SUCCESS)
799  return err;
800  break;
801 
802  default:
803  return MEMIF_ERR_UNKNOWN_MSG;;
804  break;
805  }
806 
807  if (c != NULL)
808  c->flags |= MEMIF_CONNECTION_FLAG_WRITE;
809 
810  return MEMIF_ERR_SUCCESS; /* 0 */
811 }
812 
813 int
815 {
816  DBG ("connection fd error");
817  strncpy ((char *) c->remote_disconnect_string, "connection fd error", 19);
818  int err = memif_disconnect_internal (c);
819  return err;
820 }
821 
822 /* calls memif_msg_receive to handle pending messages on socket */
823 int
825 {
826  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
827  int err;
828 
829  err = memif_msg_receive (lm, c->fd);
830  if (err != 0)
831  {
832  err = memif_disconnect_internal (c);
833  }
834  return err;
835 }
836 
837 /* get msg from msg queue buffer and send it to socket */
838 int
840 {
841  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
842  int err = MEMIF_ERR_SUCCESS; /* 0 */
843 
844 
845  if ((c->flags & MEMIF_CONNECTION_FLAG_WRITE) == 0)
846  goto done;
847 
848  memif_msg_queue_elt_t *e = c->msg_queue;
849  if (e == NULL)
850  goto done;
851 
852  c->msg_queue = c->msg_queue->next;
853 
854  c->flags &= ~MEMIF_CONNECTION_FLAG_WRITE;
855 
856  err = memif_msg_send (c->fd, &e->msg, e->fd);
857  lm->free (e);
858  goto done;
859 
860 done:
861  return err;
862 }
863 
864 int
866 {
867  int addr_len;
868  struct sockaddr_un client;
869  int conn_fd;
871 
872  DBG ("accept called");
873 
874  addr_len = sizeof (client);
875  conn_fd =
876  accept (ms->fd, (struct sockaddr *) &client, (socklen_t *) & addr_len);
877 
878  if (conn_fd < 0)
879  {
880  return memif_syscall_error_handler (errno);
881  }
882  DBG ("accept fd %d", ms->fd);
883  DBG ("conn fd %d", conn_fd);
884 
886  elt.key = conn_fd;
887  elt.data_struct = ms;
888 
889  add_list_elt (lm, &elt, &lm->pending_list, &lm->pending_list_len);
891  lm->private_ctx);
892 
893  return memif_msg_send_hello (lm, conn_fd);
894 }
895 
896 int
898 {
899  int err;
900 
901  err = memif_msg_receive (lm, fd);
902 
903  return err;
904 }
static_fn int memif_msg_receive_disconnect(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:642
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:839
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
vnet_hw_if_output_node_runtime_t * r
#define MEMIF_FD_EVENT_READ
user needs to set events that occurred on fd and pass them to memif_control_fd_handler ...
Definition: libmemif.h:91
#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
vnet_feature_config_main_t * cm
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:824
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:1635
#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
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
#define static_fn
Definition: socket.h:86
libmemif_main_t * get_libmemif_main(memif_socket_t *ms)
Definition: main.c:236
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:356
#define MEMIF_ID_ERR
Definition: socket.h:25
#define MEMIF_NOSECRET_ERR
Definition: socket.h:30
memif_region_offset_t offset
Definition: private.h:130
#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:576
#define MEMIF_MAX_LOG2_RING_SIZE
Definition: private.h:30
int __clib_unused rv
Definition: application.c:491
static_fn int memif_msg_receive_init(memif_socket_t *ms, int fd, memif_msg_t *msg)
Definition: socket.c:364
memif_msg_init_t init
Definition: memif.h:133
int memif_syscall_error_handler(int err_code)
Definition: main.c:199
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
Definition: cJSON.c:88
#define MEMIF_CONN_ERR
Definition: socket.h:27
static_fn int memif_msg_enq_connected(memif_connection_t *c)
Definition: socket.c:283
static_fn int memif_msg_enq_init(memif_connection_t *c)
Definition: socket.c:123
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:96
memif_msg_disconnect_t disconnect
Definition: memif.h:138
struct memif_msg_queue_elt * next
u32 size
Definition: vhost_user.h:125
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:897
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:261
int get_list_elt(memif_list_elt_t **e, memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:363
u32 index
Definition: flow_types.api:221
#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:164
app_rx_mq_elt_t * elt
Definition: application.c:488
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:514
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:479
#define MEMIF_MAX_S2M_RING
Definition: private.h:28
static_fn int memif_msg_receive(libmemif_main_t *lm, int ifd)
Definition: socket.c:658
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:248
memif_log2_ring_size_t log2_ring_size
Definition: private.h:128
static_fn int memif_msg_receive_hello(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:339
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:613
int memif_conn_fd_error(memif_connection_t *c)
Definition: socket.c:814
int memif_connect1(memif_connection_t *c)
Definition: main.c:1848
int free_list_elt(memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:387
#define MEMIF_FD_EVENT_WRITE
Definition: libmemif.h:92
static size_t strlcpy(char *dest, const char *src, size_t len)
Definition: memif_private.h:71
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:327
memif_region_index_t region
Definition: private.h:129
static_fn int memif_msg_enq_add_ring(memif_connection_t *c, uint8_t index, uint8_t dir)
Definition: socket.c:201
uint16_t interface_list_len
memif_region_size_t region_size
Definition: private.h:112