FD.io VPP  v19.01.3-6-g70449b9b9
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 {
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 {
105  memif_msg_t msg = { 0 };
106  memif_msg_hello_t *h = &msg.hello;
114 
115  strncpy ((char *) h->name, (char *) lm->app_name,
116  strlen ((char *) lm->app_name));
117 
118  /* msg hello is not enqueued but sent directly,
119  because it is the first msg to be sent */
120  return memif_msg_send (fd, &msg, -1);
121 }
122 
123 /* send id and secret (optional) for interface identification */
124 static_fn int
126 {
130  if (e == NULL)
131  return memif_syscall_error_handler (errno);
132  memset (e, 0, sizeof (memif_msg_queue_elt_t));
133 
134  memset (&e->msg, 0, sizeof (e->msg));
135  memif_msg_init_t *i = &e->msg.init;
136 
138  e->fd = -1;
139  i->version = MEMIF_VERSION;
140  i->id = c->args.interface_id;
141  i->mode = c->args.mode;
142 
143  strncpy ((char *) i->name, (char *) lm->app_name,
144  strlen ((char *) lm->app_name));
145  if (strlen ((char *) c->args.secret) > 0)
146  strncpy ((char *) i->secret, (char *) c->args.secret, sizeof (i->secret));
147 
148  e->next = NULL;
149  if (c->msg_queue == NULL)
150  {
151  c->msg_queue = e;
152  return MEMIF_ERR_SUCCESS; /* 0 */
153  }
154 
155  memif_msg_queue_elt_t *cur = c->msg_queue;
156  while (cur->next != NULL)
157  {
158  cur = cur->next;
159  }
160  cur->next = e;
161 
162  return MEMIF_ERR_SUCCESS; /* 0 */
163 }
164 
165 /* send information about region specified by region_index */
166 static_fn int
168 {
170  memif_region_t *mr = &c->regions[region_index];
171 
174  if (e == NULL)
175  return memif_syscall_error_handler (errno);
176 
177  memset (&e->msg, 0, sizeof (e->msg));
179 
181  e->fd = mr->fd;
182  ar->index = region_index;
183  ar->size = mr->region_size;
184 
185  e->next = NULL;
186  if (c->msg_queue == NULL)
187  {
188  c->msg_queue = e;
189  return MEMIF_ERR_SUCCESS; /* 0 */
190  }
191 
192  memif_msg_queue_elt_t *cur = c->msg_queue;
193  while (cur->next != NULL)
194  {
195  cur = cur->next;
196  }
197  cur->next = e;
198 
199  return MEMIF_ERR_SUCCESS; /* 0 */
200 }
201 
202 /* send information about ring specified by direction (S2M | M2S) and index */
203 static_fn int
204 memif_msg_enq_add_ring (memif_connection_t * c, uint8_t index, uint8_t dir)
205 {
209  if (e == NULL)
210  return memif_syscall_error_handler (errno);
211 
212  memset (&e->msg, 0, sizeof (e->msg));
214 
216 
217  /* TODO: support multiple rings */
218  memif_queue_t *mq;
219  if (dir == MEMIF_RING_M2S)
220  mq = &c->rx_queues[index];
221  else
222  mq = &c->tx_queues[index];
223 
224  e->fd = mq->int_fd;
225  ar->index = index;
226  ar->offset = mq->offset;
227  ar->region = mq->region;
228  ar->log2_ring_size = mq->log2_ring_size;
229  ar->flags = (dir == MEMIF_RING_S2M) ? MEMIF_MSG_ADD_RING_FLAG_S2M : 0;
230  ar->private_hdr_size = 0;
231 
232  e->next = NULL;
233  if (c->msg_queue == NULL)
234  {
235  c->msg_queue = e;
236  return MEMIF_ERR_SUCCESS; /* 0 */
237  }
238 
239  memif_msg_queue_elt_t *cur = c->msg_queue;
240  while (cur->next != NULL)
241  {
242  cur = cur->next;
243  }
244  cur->next = e;
245 
246  return MEMIF_ERR_SUCCESS; /* 0 */
247 }
248 
249 /* used as connection request from slave */
250 static_fn int
252 {
256  if (e == NULL)
257  return memif_syscall_error_handler (errno);
258 
259  memset (&e->msg, 0, sizeof (e->msg));
260  memif_msg_connect_t *cm = &e->msg.connect;
261 
263  e->fd = -1;
264  strncpy ((char *) cm->if_name, (char *) c->args.interface_name,
265  strlen ((char *) c->args.interface_name));
266 
267  e->next = NULL;
268  if (c->msg_queue == NULL)
269  {
270  c->msg_queue = e;
271  return MEMIF_ERR_SUCCESS; /* 0 */
272  }
273 
274  memif_msg_queue_elt_t *cur = c->msg_queue;
275  while (cur->next != NULL)
276  {
277  cur = cur->next;
278  }
279  cur->next = e;
280 
281  return MEMIF_ERR_SUCCESS; /* 0 */
282 }
283 
284 /* used as confirmation of connection by master */
285 static_fn int
287 {
291  if (e == NULL)
292  return memif_syscall_error_handler (errno);
293 
294  memset (&e->msg, 0, sizeof (e->msg));
296 
298  e->fd = -1;
299  strncpy ((char *) cm->if_name, (char *) c->args.interface_name,
300  strlen ((char *) c->args.interface_name));
301 
302  e->next = NULL;
303  if (c->msg_queue == NULL)
304  {
305  c->msg_queue = e;
306  return MEMIF_ERR_SUCCESS; /* 0 */
307  }
308 
309  memif_msg_queue_elt_t *cur = c->msg_queue;
310  while (cur->next != NULL)
311  {
312  cur = cur->next;
313  }
314  cur->next = e;
315 
316  return MEMIF_ERR_SUCCESS; /* 0 */
317 }
318 
319 /* immediately send disconnect msg */
320  /* specifie protocol for disconnect msg err_code
321  so that it will be compatible with VPP? (header/doc) */
322 int
323 memif_msg_send_disconnect (int fd, uint8_t * err_string, uint32_t err_code)
324 {
325  memif_msg_t msg = { 0 };
327 
329  d->code = err_code;
330  uint16_t l = strlen ((char *) err_string);
331  if (l > 96)
332  {
333  DBG ("Disconnect string too long. Sending first 96 characters.");
334  l = 96;
335  }
336  strncpy ((char *) d->string, (char *) err_string, l);
337 
338  return memif_msg_send (fd, &msg, -1);
339 }
340 
341 static_fn int
343 {
344  memif_msg_hello_t *h = &msg->hello;
345 
346  if (msg->hello.min_version > MEMIF_VERSION ||
348  {
349  DBG ("incompatible protocol version");
350  return MEMIF_ERR_PROTO;
351  }
352 
353  c->run_args.num_s2m_rings = memif_min (h->max_s2m_ring + 1,
354  c->args.num_s2m_rings);
355  c->run_args.num_m2s_rings = memif_min (h->max_m2s_ring + 1,
356  c->args.num_m2s_rings);
357  c->run_args.log2_ring_size = memif_min (h->max_log2_ring_size,
358  c->args.log2_ring_size);
359  c->run_args.buffer_size = c->args.buffer_size;
360  strncpy ((char *) c->remote_name, (char *) h->name,
361  strlen ((char *) h->name));
362 
363  return MEMIF_ERR_SUCCESS; /* 0 */
364 }
365 
366 /* handle interface identification (id, secret (optional)) */
367 static_fn int
369 {
370  memif_msg_init_t *i = &msg->init;
371  memif_list_elt_t *elt = NULL;
372  memif_list_elt_t elt2;
375  uint8_t err_string[96];
376  memset (err_string, 0, sizeof (char) * 96);
377  int err = MEMIF_ERR_SUCCESS; /* 0 */
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 (&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 {
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 {
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;
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;
602 
603  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
604  }
605 
606  }
607 
608  c->on_connect ((void *) c, c->private_ctx);
609 
610  return err;
611 }
612 
613 /* master -> slave */
614 static_fn int
616 {
617  memif_msg_connect_t *cm = &msg->connect;
619 
620  int err;
621  err = memif_connect1 (c);
622  if (err != MEMIF_ERR_SUCCESS)
623  return err;
624 
625  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
626  strlen ((char *) cm->if_name));
627 
628  int i;
629  if (c->on_interrupt != NULL)
630  {
631  for (i = 0; i < c->run_args.num_s2m_rings; i++)
632  {
633  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
634  }
635  }
636 
637  c->on_connect ((void *) c, c->private_ctx);
638 
639  return err;
640 }
641 
642 static_fn int
644 {
646 
647  memset (c->remote_disconnect_string, 0,
648  sizeof (c->remote_disconnect_string));
649  strncpy ((char *) c->remote_disconnect_string, (char *) d->string,
650  strlen ((char *) d->string));
651 
652  /* on returning error, handle function will call memif_disconnect () */
653  DBG ("disconnect received: %s, mode: %d",
654  c->remote_disconnect_string, c->args.mode);
655  return MEMIF_ERR_DISCONNECT;
656 }
657 
658 static_fn int
660 {
661  char ctl[CMSG_SPACE (sizeof (int)) +
662  CMSG_SPACE (sizeof (struct ucred))] = { 0 };
663  struct msghdr mh = { 0 };
664  struct iovec iov[1];
665  memif_msg_t msg = { 0 };
666  ssize_t size;
667  int err = MEMIF_ERR_SUCCESS; /* 0 */
668  int fd = -1;
669  int i;
672  memif_socket_t *ms = NULL;
673  memif_list_elt_t *elt = NULL;
674 
675  iov[0].iov_base = (void *) &msg;
676  iov[0].iov_len = sizeof (memif_msg_t);
677  mh.msg_iov = iov;
678  mh.msg_iovlen = 1;
679  mh.msg_control = ctl;
680  mh.msg_controllen = sizeof (ctl);
681 
682  DBG ("recvmsg fd %d", ifd);
683  size = recvmsg (ifd, &mh, 0);
684  DBG ("done");
685  if (size != sizeof (memif_msg_t))
686  {
687  if (size == 0)
688  return MEMIF_ERR_DISCONNECTED;
689  else
690  return MEMIF_ERR_MFMSG;
691  }
692 
693  struct cmsghdr *cmsg;
694 
695  cmsg = CMSG_FIRSTHDR (&mh);
696  while (cmsg)
697  {
698  if (cmsg->cmsg_level == SOL_SOCKET)
699  {
700  if (cmsg->cmsg_type == SCM_CREDENTIALS)
701  {
702  /* Do nothing */ ;
703  }
704  else if (cmsg->cmsg_type == SCM_RIGHTS)
705  {
706  int *fdp = (int *) CMSG_DATA (cmsg);
707  fd = *fdp;
708  }
709  }
710  cmsg = CMSG_NXTHDR (&mh, cmsg);
711  }
712 
713  DBG ("Message type %u received", msg.type);
714 
715  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
716  if (elt != NULL)
717  c = (memif_connection_t *) elt->data_struct;
718 
719  switch (msg.type)
720  {
721  case MEMIF_MSG_TYPE_ACK:
722  break;
723 
725  if ((err = memif_msg_receive_hello (c, &msg)) != MEMIF_ERR_SUCCESS)
726  return err;
728  return err;
729  if ((err = memif_msg_enq_init (c)) != MEMIF_ERR_SUCCESS)
730  return err;
731  for (i = 0; i < c->regions_num; i++)
732  {
733  if ((err = memif_msg_enq_add_region (c, i)) != MEMIF_ERR_SUCCESS)
734  return err;
735  }
736  for (i = 0; i < c->run_args.num_s2m_rings; i++)
737  {
738  if ((err =
741  return err;
742  }
743  for (i = 0; i < c->run_args.num_m2s_rings; i++)
744  {
745  if ((err =
748  return err;
749  }
750  if ((err = memif_msg_enq_connect (c)) != MEMIF_ERR_SUCCESS)
751  return err;
752  break;
753 
754  case MEMIF_MSG_TYPE_INIT:
755  get_list_elt (&elt, lm->pending_list, lm->pending_list_len, ifd);
756  if (elt == NULL)
757  return -1;
758  ms = (memif_socket_t *) elt->data_struct;
759  if ((err = memif_msg_receive_init (ms, ifd, &msg)) != MEMIF_ERR_SUCCESS)
760  return err;
761  /* c->remote_pid = cr->pid */
762  /* c->remote_uid = cr->uid */
763  /* c->remote_gid = cr->gid */
764  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
765  if (elt == NULL)
766  return -1;
767  c = (memif_connection_t *) elt->data_struct;
768  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
769  return err;
770  break;
771 
773  if ((err =
775  return err;
776  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
777  return err;
778  break;
779 
781  if ((err =
783  return err;
784  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
785  return err;
786  break;
787 
789  if ((err = memif_msg_receive_connect (c, &msg)) != MEMIF_ERR_SUCCESS)
790  return err;
791  if ((err = memif_msg_enq_connected (c)) != MEMIF_ERR_SUCCESS)
792  return err;
793  break;
794 
796  if ((err = memif_msg_receive_connected (c, &msg)) != MEMIF_ERR_SUCCESS)
797  return err;
798  break;
799 
801  if ((err = memif_msg_receive_disconnect (c, &msg)) != MEMIF_ERR_SUCCESS)
802  return err;
803  break;
804 
805  default:
806  return MEMIF_ERR_UNKNOWN_MSG;;
807  break;
808  }
809 
810  if (c != NULL)
811  c->flags |= MEMIF_CONNECTION_FLAG_WRITE;
812 /* libmemif_main_t *lm = &libmemif_main;
813  lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD); */
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  int err;
831  err = memif_msg_receive (c->fd);
832  if (err != 0)
833  {
834  err = memif_disconnect_internal (c);
835  }
836  return err;
837 }
838 
839 /* get msg from msg queue buffer and send it to socket */
840 int
842 {
844  int err = MEMIF_ERR_SUCCESS; /* 0 */
845 
846 
847  if ((c->flags & MEMIF_CONNECTION_FLAG_WRITE) == 0)
848  goto done;
849 
850  memif_msg_queue_elt_t *e = c->msg_queue;
851  if (e == NULL)
852  goto done;
853 
854  c->msg_queue = c->msg_queue->next;
855 
856  c->flags &= ~MEMIF_CONNECTION_FLAG_WRITE;
857 /*
858  libmemif_main_t *lm = &libmemif_main;
859 
860  lm->control_fd_update (c->fd,
861  MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_WRITE | MEMIF_FD_EVENT_MOD);
862 */
863  err = memif_msg_send (c->fd, &e->msg, e->fd);
864  lm->free (e);
865  goto done;
866 
867 done:
868  return err;
869 }
870 
871 int
873 {
874  int addr_len;
875  struct sockaddr_un client;
876  int conn_fd;
878 
879  DBG ("accept called");
880 
881  addr_len = sizeof (client);
882  conn_fd =
883  accept (ms->fd, (struct sockaddr *) &client, (socklen_t *) & addr_len);
884 
885  if (conn_fd < 0)
886  {
887  return memif_syscall_error_handler (errno);
888  }
889  DBG ("accept fd %d", ms->fd);
890  DBG ("conn fd %d", conn_fd);
891 
892  memif_list_elt_t elt;
893  elt.key = conn_fd;
894  elt.data_struct = ms;
895 
896  add_list_elt (&elt, &lm->pending_list, &lm->pending_list_len);
898 
899  return memif_msg_send_hello (conn_fd);
900 }
901 
902 int
904 {
905  int err;
906  DBG ("call recv");
907  err = memif_msg_receive (fd);
908  DBG ("recv finished");
909  return err;
910 }
static_fn int memif_msg_receive_disconnect(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:643
memif_version_t max_version
Definition: memif.h:76
memif_interface_mode_t mode
Definition: memif.h:87
int memif_conn_fd_write_ready(memif_connection_t *c)
Definition: socket.c:841
clib_error_t * memif_conn_fd_accept_ready(clib_file_t *uf)
Definition: socket.c:649
memif_msg_add_region_t add_region
Definition: memif.h:132
#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:88
#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:122
#define MEMIF_SLAVE_ERR
Definition: socket.h:26
#define NULL
Definition: clib.h:58
memif_msg_add_ring_t add_ring
Definition: memif.h:133
#define MEMIF_MSG_ADD_RING_FLAG_S2M
Definition: memif.h:101
#define MEMIF_MAX_REGION
Definition: private.h:29
memif_list_elt_t * pending_list
int memif_conn_fd_read_ready(memif_connection_t *c)
Definition: socket.c:828
int i
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:1115
#define MEMIF_CONNECTION_FLAG_WRITE
memif_control_fd_update_t * control_fd_update
memif_region_index_t region
Definition: memif.h:103
memif_version_t min_version
Definition: memif.h:75
uint8_t secret[24]
Definition: memif.h:88
uint16_t private_hdr_size
Definition: memif.h:106
memif_list_elt_t * interface_list
memif_interface_id_t id
Definition: memif.h:86
uint8_t name[32]
Definition: memif.h:74
#define static_fn
Definition: socket.h:86
memif_realloc_t * realloc
memif_ring_index_t max_m2s_ring
Definition: memif.h:78
memif_free_t * free
clib_error_t * memif_init_regions_and_queues(memif_if_t *mif)
Definition: memif.c:303
#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:104
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:368
memif_msg_init_t init
Definition: memif.h:131
int memif_syscall_error_handler(int err_code)
Definition: main.c:204
memif_ring_index_t index
Definition: memif.h:102
memif_list_elt_t * interrupt_list
clib_error_t * memif_msg_send_disconnect(memif_if_t *mif, clib_error_t *err)
Definition: socket.c:190
uword size
#define MEMIF_CONN_ERR
Definition: socket.h:27
static_fn int memif_msg_enq_connected(memif_connection_t *c)
Definition: socket.c:286
static_fn int memif_msg_enq_init(memif_connection_t *c)
Definition: socket.c:125
#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:93
memif_msg_disconnect_t disconnect
Definition: memif.h:136
struct memif_msg_queue_elt * next
Definition: memif_private.h:97
static_fn int memif_msg_enq_ack(memif_connection_t *c)
Definition: socket.c:72
static_fn int memif_msg_send_hello(int fd)
Definition: socket.c:102
memif_msg_hello_t hello
Definition: memif.h:130
memif_log2_ring_size_t max_log2_ring_size
Definition: memif.h:80
int add_list_elt(memif_list_elt_t *e, memif_list_elt_t **list, uint16_t *len)
Definition: main.c:319
uint8_t if_name[32]
Definition: memif.h:111
uint8_t name[32]
Definition: memif.h:89
svmdb_client_t * c
uint8_t if_name[32]
Definition: memif.h:116
int get_list_elt(memif_list_elt_t **e, memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:354
memif_alloc_t * alloc
#define MEMIF_MODE_ERR
Definition: socket.h:28
#define DBG(...)
memif_region_index_t index
Definition: memif.h:94
int memif_read_ready(int fd)
Definition: socket.c:903
memif_log2_ring_size_t log2_ring_size
Definition: memif.h:105
memif_version_t version
Definition: memif.h:85
#define memif_min(a, b)
Definition: memif_private.h:53
memif_ring_index_t max_s2m_ring
Definition: memif.h:79
static_fn int memif_msg_enq_add_region(memif_connection_t *c, uint8_t region_index)
Definition: socket.c:167
memif_msg_connect_t connect
Definition: memif.h:134
#define MEMIF_VERSION
Definition: memif.h:28
uint16_t interrupt_list_len
static_fn int memif_msg_receive_add_ring(memif_connection_t *c, memif_msg_t *msg, int fd)
Definition: socket.c:518
static_fn int memif_msg_receive(int ifd)
Definition: socket.c:659
uint16_t flags
Definition: memif.h:100
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
uint8_t app_name[MEMIF_NAME_LEN]
memif_region_size_t size
Definition: memif.h:95
memif_region_index_t max_region
Definition: memif.h:77
memif_msg_type_t type
Definition: memif.h:127
uint16_t pending_list_len
memif_list_elt_t * control_list
static_fn int memif_msg_enq_connect(memif_connection_t *c)
Definition: socket.c:251
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:342
memif_msg_connected_t connected
Definition: memif.h:135
uint16_t control_list_len
#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:615
int memif_conn_fd_error(memif_connection_t *c)
Definition: socket.c:818
int memif_connect1(memif_connection_t *c)
Definition: main.c:1309
libmemif_main_t libmemif_main
Definition: main.c:68
int free_list_elt(memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:377
#define MEMIF_FD_EVENT_WRITE
Definition: libmemif.h:89
memif_get_external_region_addr_t * get_external_region_addr
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:204
uint16_t interface_list_len
memif_region_size_t region_size
Definition: private.h:103