FD.io VPP  v18.07-34-g55fbdb9
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, 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 {
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 {
169  /* maybe check if region is valid? */
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  int err_disc;
379  if (i->version != MEMIF_VERSION)
380  {
381  DBG ("MEMIF_VER_ERR");
382  strncpy ((char *) err_string, MEMIF_VER_ERR, strlen (MEMIF_VER_ERR));
383  err = MEMIF_ERR_PROTO;
384  goto error;
385  }
386 
387  get_list_elt (&elt, ms->interface_list, ms->interface_list_len, i->id);
388  if (elt == NULL)
389  {
390  DBG ("MEMIF_ID_ERR");
391  strncpy ((char *) err_string, MEMIF_ID_ERR, strlen (MEMIF_ID_ERR));
392  err = MEMIF_ERR_ID;
393  goto error;
394  }
395 
396  c = (memif_connection_t *) elt->data_struct;
397 
398  if (!(c->args.is_master))
399  {
400  DBG ("MEMIF_SLAVE_ERR");
401  strncpy ((char *) err_string, MEMIF_SLAVE_ERR,
402  strlen (MEMIF_SLAVE_ERR));
403  err = MEMIF_ERR_ACCSLAVE;
404  goto error;
405  }
406  if (c->fd != -1)
407  {
408  DBG ("MEMIF_CONN_ERR");
409  strncpy ((char *) err_string, MEMIF_CONN_ERR, strlen (MEMIF_CONN_ERR));
410  err = MEMIF_ERR_ALRCONN;
411  goto error;
412  }
413 
414  c->fd = fd;
415 
416  if (i->mode != c->args.mode)
417  {
418  DBG ("MEMIF_MODE_ERR");
419  strncpy ((char *) err_string, MEMIF_MODE_ERR, strlen (MEMIF_MODE_ERR));
420  err = MEMIF_ERR_MODE;
421  goto error;
422  }
423 
424  strncpy ((char *) c->remote_name, (char *) i->name,
425  strlen ((char *) i->name));
426 
427  if (strlen((char *) c->args.secret) > 0)
428  {
429  int r;
430  if (strlen((char *) i->secret) > 0)
431  {
432  if (strlen ((char *) c->args.secret) != strlen ((char *) i->secret))
433  {
434  DBG ("MEMIF_SECRET_ERR");
435  strncpy ((char *) err_string,
437  err = MEMIF_ERR_SECRET;
438  goto error;
439  }
440  r = strncmp ((char *) i->secret, (char *) c->args.secret,
441  strlen ((char *) c->args.secret));
442  if (r != 0)
443  {
444  DBG ("MEMIF_SECRET_ERR");
445  strncpy ((char *) err_string,
447  err = MEMIF_ERR_SECRET;
448  goto error;
449  }
450  }
451  else
452  {
453  DBG ("MEMIF_NOSECRET_ERR");
454  strncpy ((char *) err_string,
456  err = MEMIF_ERR_NOSECRET;
457  goto error;
458  }
459  }
460 
461  c->read_fn = memif_conn_fd_read_ready;
462  c->write_fn = memif_conn_fd_write_ready;
463  c->error_fn = memif_conn_fd_error;
464 
465  elt2.key = c->fd;
466  elt2.data_struct = c;
467 
468  add_list_elt (&elt2, &lm->control_list, &lm->control_list_len);
470 
471  return err;
472 
473 error:
474  memif_msg_send_disconnect (fd, err_string, 0);
477  close (fd);
478  fd = -1;
479  return err;
480 }
481 
482 /* receive region information and add new region to connection (if possible) */
483 static_fn int
485  int fd)
486 {
488  memif_region_t *mr;
489  if (fd < 0)
490  return MEMIF_ERR_NO_SHMFD;
491 
492  if (ar->index > MEMIF_MAX_REGION)
493  return MEMIF_ERR_MAXREG;
494 
495  mr =
496  (memif_region_t *) realloc (c->regions,
497  sizeof (memif_region_t) * (ar->index + 1));
498  if (mr == NULL)
499  return memif_syscall_error_handler (errno);
500  c->regions = mr;
501  c->regions[ar->index].fd = fd;
502  c->regions[ar->index].region_size = ar->size;
503  c->regions[ar->index].shm = NULL;
504 
505  return MEMIF_ERR_SUCCESS; /* 0 */
506 }
507 
508 /* receive ring information and add new ring to connection queue
509  (based on direction S2M | M2S) */
510 static_fn int
512 {
513  memif_msg_add_ring_t *ar = &msg->add_ring;
514 
515  memif_queue_t *mq;
516 
517  if (fd < 0)
518  return MEMIF_ERR_NO_INTFD;
519 
520  if (ar->private_hdr_size != 0)
521  return MEMIF_ERR_PRIVHDR;
522 
524  {
525  if (ar->index > MEMIF_MAX_S2M_RING)
526  return MEMIF_ERR_MAXRING;
527  if (ar->index >= c->args.num_s2m_rings)
528  return MEMIF_ERR_MAXRING;
529 
530  mq =
531  (memif_queue_t *) realloc (c->rx_queues,
532  sizeof (memif_queue_t) * (ar->index + 1));
533  memset (mq + ar->index, 0, sizeof (memif_queue_t));
534  if (mq == NULL)
535  return memif_syscall_error_handler (errno);
536  c->rx_queues = mq;
537  c->rx_queues[ar->index].int_fd = fd;
538  c->rx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
539  c->rx_queues[ar->index].region = ar->region;
540  c->rx_queues[ar->index].offset = ar->offset;
541  c->run_args.num_s2m_rings++;
542  }
543  else
544  {
545  if (ar->index > MEMIF_MAX_M2S_RING)
546  return MEMIF_ERR_MAXRING;
547  if (ar->index >= c->args.num_m2s_rings)
548  return MEMIF_ERR_MAXRING;
549 
550  mq =
551  (memif_queue_t *) realloc (c->tx_queues,
552  sizeof (memif_queue_t) * (ar->index + 1));
553  memset (mq + ar->index, 0, sizeof (memif_queue_t));
554  if (mq == NULL)
555  return memif_syscall_error_handler (errno);
556  c->tx_queues = mq;
557  c->tx_queues[ar->index].int_fd = fd;
558  c->tx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
559  c->tx_queues[ar->index].region = ar->region;
560  c->tx_queues[ar->index].offset = ar->offset;
561  c->run_args.num_m2s_rings++;
562  }
563 
564  return MEMIF_ERR_SUCCESS; /* 0 */
565 }
566 
567 /* slave -> master */
568 static_fn int
570 {
571  memif_msg_connect_t *cm = &msg->connect;
573  memif_list_elt_t elt;
574 
575  int err;
576  err = memif_connect1 (c);
577  if (err != MEMIF_ERR_SUCCESS)
578  return err;
579 
580  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
581  strlen ((char *) cm->if_name));
582 
583  int i;
584  if (c->on_interrupt != NULL)
585  {
586  for (i = 0; i < c->run_args.num_m2s_rings; i++)
587  {
588  elt.key = c->rx_queues[i].int_fd;
589  elt.data_struct = c;
591 
592  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
593  }
594 
595  }
596 
597  c->on_connect ((void *) c, c->private_ctx);
598 
599  return err;
600 }
601 
602 /* master -> slave */
603 static_fn int
605 {
606  memif_msg_connect_t *cm = &msg->connect;
608 
609  int err;
610  err = memif_connect1 (c);
611  if (err != MEMIF_ERR_SUCCESS)
612  return err;
613 
614  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
615  strlen ((char *) cm->if_name));
616 
617  int i;
618  if (c->on_interrupt != NULL)
619  {
620  for (i = 0; i < c->run_args.num_s2m_rings; i++)
621  {
622  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
623  }
624  }
625 
626  c->on_connect ((void *) c, c->private_ctx);
627 
628  return err;
629 }
630 
631 static_fn int
633 {
635 
636  memset (c->remote_disconnect_string, 0,
637  sizeof (c->remote_disconnect_string));
638  strncpy ((char *) c->remote_disconnect_string, (char *) d->string,
639  strlen ((char *) d->string));
640 
641  /* on returning error, handle function will call memif_disconnect () */
642  DBG ("disconnect received: %s, mode: %d",
643  c->remote_disconnect_string, c->args.mode);
644  return MEMIF_ERR_DISCONNECT;
645 }
646 
647 static_fn int
649 {
650  char ctl[CMSG_SPACE (sizeof (int)) +
651  CMSG_SPACE (sizeof (struct ucred))] = { 0 };
652  struct msghdr mh = { 0 };
653  struct iovec iov[1];
654  memif_msg_t msg = { 0 };
655  ssize_t size;
656  int err = MEMIF_ERR_SUCCESS; /* 0 */
657  int fd = -1;
658  int i;
661  memif_socket_t *ms = NULL;
662  memif_list_elt_t *elt = NULL;
663 
664  iov[0].iov_base = (void *) &msg;
665  iov[0].iov_len = sizeof (memif_msg_t);
666  mh.msg_iov = iov;
667  mh.msg_iovlen = 1;
668  mh.msg_control = ctl;
669  mh.msg_controllen = sizeof (ctl);
670 
671  DBG ("recvmsg fd %d", ifd);
672  size = recvmsg (ifd, &mh, 0);
673  DBG ("done");
674  if (size != sizeof (memif_msg_t))
675  {
676  if (size == 0)
677  return MEMIF_ERR_DISCONNECTED;
678  else
679  return MEMIF_ERR_MFMSG;
680  }
681 
682  struct ucred *cr = 0;
683  struct cmsghdr *cmsg;
684 
685  cmsg = CMSG_FIRSTHDR (&mh);
686  while (cmsg)
687  {
688  if (cmsg->cmsg_level == SOL_SOCKET)
689  {
690  if (cmsg->cmsg_type == SCM_CREDENTIALS)
691  {
692  cr = (struct ucred *) CMSG_DATA (cmsg);
693  }
694  else if (cmsg->cmsg_type == SCM_RIGHTS)
695  {
696  int *fdp = (int *) CMSG_DATA (cmsg);
697  fd = *fdp;
698  }
699  }
700  cmsg = CMSG_NXTHDR (&mh, cmsg);
701  }
702 
703  DBG ("Message type %u received", msg.type);
704 
705  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
706  if (elt != NULL)
707  c = (memif_connection_t *) elt->data_struct;
708 
709  switch (msg.type)
710  {
711  case MEMIF_MSG_TYPE_ACK:
712  break;
713 
715  if ((err = memif_msg_receive_hello (c, &msg)) != MEMIF_ERR_SUCCESS)
716  return err;
718  return err;
719  if ((err = memif_msg_enq_init (c)) != MEMIF_ERR_SUCCESS)
720  return err;
721  if ((err = memif_msg_enq_add_region (c, 0)) != MEMIF_ERR_SUCCESS)
722  return err;
723  for (i = 0; i < c->run_args.num_s2m_rings; i++)
724  {
725  if ((err =
728  return err;
729  }
730  for (i = 0; i < c->run_args.num_m2s_rings; i++)
731  {
732  if ((err =
735  return err;
736  }
737  if ((err = memif_msg_enq_connect (c)) != MEMIF_ERR_SUCCESS)
738  return err;
739  break;
740 
741  case MEMIF_MSG_TYPE_INIT:
742  get_list_elt (&elt, lm->pending_list, lm->pending_list_len, ifd);
743  if (elt == NULL)
744  return -1;
745  ms = (memif_socket_t *) elt->data_struct;
746  if ((err = memif_msg_receive_init (ms, ifd, &msg)) != MEMIF_ERR_SUCCESS)
747  return err;
748  /* c->remote_pid = cr->pid */
749  /* c->remote_uid = cr->uid */
750  /* c->remote_gid = cr->gid */
751  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
752  if (elt == NULL)
753  return -1;
754  c = (memif_connection_t *) elt->data_struct;
755  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
756  return err;
757  break;
758 
760  if ((err =
762  return err;
763  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
764  return err;
765  break;
766 
768  if ((err =
770  return err;
771  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
772  return err;
773  break;
774 
776  if ((err = memif_msg_receive_connect (c, &msg)) != MEMIF_ERR_SUCCESS)
777  return err;
778  if ((err = memif_msg_enq_connected (c)) != MEMIF_ERR_SUCCESS)
779  return err;
780  break;
781 
783  if ((err = memif_msg_receive_connected (c, &msg)) != MEMIF_ERR_SUCCESS)
784  return err;
785  break;
786 
788  if ((err = memif_msg_receive_disconnect (c, &msg)) != MEMIF_ERR_SUCCESS)
789  return err;
790  break;
791 
792  default:
793  return MEMIF_ERR_UNKNOWN_MSG;;
794  break;
795  }
796 
797  if (c != NULL)
798  c->flags |= MEMIF_CONNECTION_FLAG_WRITE;
799 /* libmemif_main_t *lm = &libmemif_main;
800  lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD); */
801  return MEMIF_ERR_SUCCESS; /* 0 */
802 }
803 
804 int
806 {
807  DBG ("connection fd error");
808  strncpy ((char *) c->remote_disconnect_string, "connection fd error", 19);
809  int err = memif_disconnect_internal (c);
810  return err;
811 }
812 
813 /* calls memif_msg_receive to handle pending messages on socket */
814 int
816 {
817  int err;
818  err = memif_msg_receive (c->fd);
819  if (err != 0)
820  {
821  err = memif_disconnect_internal (c);
822  }
823  return err;
824 }
825 
826 /* get msg from msg queue buffer and send it to socket */
827 int
829 {
831  int err = MEMIF_ERR_SUCCESS; /* 0 */
832 
833 
834  if ((c->flags & MEMIF_CONNECTION_FLAG_WRITE) == 0)
835  goto done;
836 
837  memif_msg_queue_elt_t *e = c->msg_queue;
838  if (e == NULL)
839  goto done;
840 
841  c->msg_queue = c->msg_queue->next;
842 
843  c->flags &= ~MEMIF_CONNECTION_FLAG_WRITE;
844 /*
845  libmemif_main_t *lm = &libmemif_main;
846 
847  lm->control_fd_update (c->fd,
848  MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_WRITE | MEMIF_FD_EVENT_MOD);
849 */
850  err = memif_msg_send (c->fd, &e->msg, e->fd);
851  lm->free (e);
852  goto done;
853 
854 done:
855  return err;
856 }
857 
858 int
860 {
861  int addr_len;
862  struct sockaddr_un client;
863  int conn_fd;
865 
866  DBG ("accept called");
867 
868  addr_len = sizeof (client);
869  conn_fd =
870  accept (ms->fd, (struct sockaddr *) &client, (socklen_t *) & addr_len);
871 
872  if (conn_fd < 0)
873  {
874  return memif_syscall_error_handler (errno);
875  }
876  DBG ("accept fd %d", ms->fd);
877  DBG ("conn fd %d", conn_fd);
878 
879  memif_list_elt_t elt;
880  elt.key = conn_fd;
881  elt.data_struct = ms;
882 
883  add_list_elt (&elt, &lm->pending_list, &lm->pending_list_len);
885 
886  return memif_msg_send_hello (conn_fd);
887 }
888 
889 int
891 {
892  int err;
893  DBG ("call recv");
894  err = memif_msg_receive (fd);
895  DBG ("recv finished");
896  return err;
897 }
static_fn int memif_msg_receive_disconnect(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:632
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:828
clib_error_t * memif_conn_fd_accept_ready(clib_file_t *uf)
Definition: socket.c:650
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:87
#define MEMIF_SECRET_ERR
Definition: socket.h:29
uint8_t string[96]
Definition: memif.h:122
#define MEMIF_SLAVE_ERR
Definition: socket.h:26
#define NULL
Definition: clib.h:55
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:815
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:1077
#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_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:304
#define MEMIF_ID_ERR
Definition: socket.h:25
#define MEMIF_NOSECRET_ERR
Definition: socket.h:30
memif_region_offset_t offset
Definition: private.h:89
#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:569
#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:202
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
int int_fd
Definition: private.h:96
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:124
#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:92
memif_msg_disconnect_t disconnect
Definition: memif.h:136
struct memif_msg_queue_elt * next
Definition: memif_private.h:96
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:313
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:348
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:890
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:166
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:511
static_fn int memif_msg_receive(int ifd)
Definition: socket.c:648
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:484
#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:87
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:604
int memif_conn_fd_error(memif_connection_t *c)
Definition: socket.c:805
int memif_connect1(memif_connection_t *c)
Definition: main.c:1259
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:371
#define MEMIF_FD_EVENT_WRITE
Definition: libmemif.h:88
memif_region_index_t region
Definition: private.h:88
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:72