FD.io VPP  v18.10-32-g1161dda
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  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 
490  memif_region_t *mr;
491  if (fd < 0)
492  return MEMIF_ERR_NO_SHMFD;
493 
494  if (ar->index > MEMIF_MAX_REGION)
495  return MEMIF_ERR_MAXREG;
496 
497  mr =
498  (memif_region_t *) lm->realloc (c->regions,
499  sizeof (memif_region_t) *
500  (++c->regions_num));
501  if (mr == NULL)
502  return memif_syscall_error_handler (errno);
503  memset (mr + ar->index, 0, sizeof (memif_region_t));
504  c->regions = mr;
505  c->regions[ar->index].fd = fd;
506  c->regions[ar->index].region_size = ar->size;
507  c->regions[ar->index].addr = NULL;
508 
509  /* region 0 is never external */
510  if (lm->get_external_region_addr && (ar->index != 0))
511  c->regions[ar->index].is_external = 1;
512 
513  return MEMIF_ERR_SUCCESS; /* 0 */
514 }
515 
516 /* receive ring information and add new ring to connection queue
517  (based on direction S2M | M2S) */
518 static_fn int
520 {
522 
523  memif_msg_add_ring_t *ar = &msg->add_ring;
524 
525  memif_queue_t *mq;
526 
527  if (fd < 0)
528  return MEMIF_ERR_NO_INTFD;
529 
530  if (ar->private_hdr_size != 0)
531  return MEMIF_ERR_PRIVHDR;
532 
534  {
535  if (ar->index > MEMIF_MAX_S2M_RING)
536  return MEMIF_ERR_MAXRING;
537  if (ar->index >= c->args.num_s2m_rings)
538  return MEMIF_ERR_MAXRING;
539 
540  mq =
541  (memif_queue_t *) lm->realloc (c->rx_queues,
542  sizeof (memif_queue_t) *
543  (++c->rx_queues_num));
544  memset (mq + ar->index, 0, sizeof (memif_queue_t));
545  if (mq == NULL)
546  return memif_syscall_error_handler (errno);
547  c->rx_queues = mq;
548  c->rx_queues[ar->index].int_fd = fd;
549  c->rx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
550  c->rx_queues[ar->index].region = ar->region;
551  c->rx_queues[ar->index].offset = ar->offset;
552  c->run_args.num_s2m_rings++;
553  }
554  else
555  {
556  if (ar->index > MEMIF_MAX_M2S_RING)
557  return MEMIF_ERR_MAXRING;
558  if (ar->index >= c->args.num_m2s_rings)
559  return MEMIF_ERR_MAXRING;
560 
561  mq =
562  (memif_queue_t *) lm->realloc (c->tx_queues,
563  sizeof (memif_queue_t) *
564  (++c->tx_queues_num));
565  memset (mq + ar->index, 0, sizeof (memif_queue_t));
566  if (mq == NULL)
567  return memif_syscall_error_handler (errno);
568  c->tx_queues = mq;
569  c->tx_queues[ar->index].int_fd = fd;
570  c->tx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
571  c->tx_queues[ar->index].region = ar->region;
572  c->tx_queues[ar->index].offset = ar->offset;
573  c->run_args.num_m2s_rings++;
574  }
575 
576  return MEMIF_ERR_SUCCESS; /* 0 */
577 }
578 
579 /* slave -> master */
580 static_fn int
582 {
583  memif_msg_connect_t *cm = &msg->connect;
585  memif_list_elt_t elt;
586 
587  int err;
588  err = memif_connect1 (c);
589  if (err != MEMIF_ERR_SUCCESS)
590  return err;
591 
592  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
593  strlen ((char *) cm->if_name));
594 
595  int i;
596  if (c->on_interrupt != NULL)
597  {
598  for (i = 0; i < c->run_args.num_m2s_rings; i++)
599  {
600  elt.key = c->rx_queues[i].int_fd;
601  elt.data_struct = c;
603 
604  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
605  }
606 
607  }
608 
609  c->on_connect ((void *) c, c->private_ctx);
610 
611  return err;
612 }
613 
614 /* master -> slave */
615 static_fn int
617 {
618  memif_msg_connect_t *cm = &msg->connect;
620 
621  int err;
622  err = memif_connect1 (c);
623  if (err != MEMIF_ERR_SUCCESS)
624  return err;
625 
626  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
627  strlen ((char *) cm->if_name));
628 
629  int i;
630  if (c->on_interrupt != NULL)
631  {
632  for (i = 0; i < c->run_args.num_s2m_rings; i++)
633  {
634  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
635  }
636  }
637 
638  c->on_connect ((void *) c, c->private_ctx);
639 
640  return err;
641 }
642 
643 static_fn int
645 {
647 
648  memset (c->remote_disconnect_string, 0,
649  sizeof (c->remote_disconnect_string));
650  strncpy ((char *) c->remote_disconnect_string, (char *) d->string,
651  strlen ((char *) d->string));
652 
653  /* on returning error, handle function will call memif_disconnect () */
654  DBG ("disconnect received: %s, mode: %d",
655  c->remote_disconnect_string, c->args.mode);
656  return MEMIF_ERR_DISCONNECT;
657 }
658 
659 static_fn int
661 {
662  char ctl[CMSG_SPACE (sizeof (int)) +
663  CMSG_SPACE (sizeof (struct ucred))] = { 0 };
664  struct msghdr mh = { 0 };
665  struct iovec iov[1];
666  memif_msg_t msg = { 0 };
667  ssize_t size;
668  int err = MEMIF_ERR_SUCCESS; /* 0 */
669  int fd = -1;
670  int i;
673  memif_socket_t *ms = NULL;
674  memif_list_elt_t *elt = NULL;
675 
676  iov[0].iov_base = (void *) &msg;
677  iov[0].iov_len = sizeof (memif_msg_t);
678  mh.msg_iov = iov;
679  mh.msg_iovlen = 1;
680  mh.msg_control = ctl;
681  mh.msg_controllen = sizeof (ctl);
682 
683  DBG ("recvmsg fd %d", ifd);
684  size = recvmsg (ifd, &mh, 0);
685  DBG ("done");
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 ucred *cr = 0;
695  struct cmsghdr *cmsg;
696 
697  cmsg = CMSG_FIRSTHDR (&mh);
698  while (cmsg)
699  {
700  if (cmsg->cmsg_level == SOL_SOCKET)
701  {
702  if (cmsg->cmsg_type == SCM_CREDENTIALS)
703  {
704  cr = (struct ucred *) CMSG_DATA (cmsg);
705  }
706  else if (cmsg->cmsg_type == SCM_RIGHTS)
707  {
708  int *fdp = (int *) CMSG_DATA (cmsg);
709  fd = *fdp;
710  }
711  }
712  cmsg = CMSG_NXTHDR (&mh, cmsg);
713  }
714 
715  DBG ("Message type %u received", msg.type);
716 
717  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
718  if (elt != NULL)
719  c = (memif_connection_t *) elt->data_struct;
720 
721  switch (msg.type)
722  {
723  case MEMIF_MSG_TYPE_ACK:
724  break;
725 
727  if ((err = memif_msg_receive_hello (c, &msg)) != MEMIF_ERR_SUCCESS)
728  return err;
730  return err;
731  if ((err = memif_msg_enq_init (c)) != MEMIF_ERR_SUCCESS)
732  return err;
733  for (i = 0; i < c->regions_num; i++)
734  {
735  if ((err = memif_msg_enq_add_region (c, i)) != MEMIF_ERR_SUCCESS)
736  return err;
737  }
738  for (i = 0; i < c->run_args.num_s2m_rings; i++)
739  {
740  if ((err =
743  return err;
744  }
745  for (i = 0; i < c->run_args.num_m2s_rings; i++)
746  {
747  if ((err =
750  return err;
751  }
752  if ((err = memif_msg_enq_connect (c)) != MEMIF_ERR_SUCCESS)
753  return err;
754  break;
755 
756  case MEMIF_MSG_TYPE_INIT:
757  get_list_elt (&elt, lm->pending_list, lm->pending_list_len, ifd);
758  if (elt == NULL)
759  return -1;
760  ms = (memif_socket_t *) elt->data_struct;
761  if ((err = memif_msg_receive_init (ms, ifd, &msg)) != MEMIF_ERR_SUCCESS)
762  return err;
763  /* c->remote_pid = cr->pid */
764  /* c->remote_uid = cr->uid */
765  /* c->remote_gid = cr->gid */
766  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
767  if (elt == NULL)
768  return -1;
769  c = (memif_connection_t *) elt->data_struct;
770  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
771  return err;
772  break;
773 
775  if ((err =
777  return err;
778  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
779  return err;
780  break;
781 
783  if ((err =
785  return err;
786  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
787  return err;
788  break;
789 
791  if ((err = memif_msg_receive_connect (c, &msg)) != MEMIF_ERR_SUCCESS)
792  return err;
793  if ((err = memif_msg_enq_connected (c)) != MEMIF_ERR_SUCCESS)
794  return err;
795  break;
796 
798  if ((err = memif_msg_receive_connected (c, &msg)) != MEMIF_ERR_SUCCESS)
799  return err;
800  break;
801 
803  if ((err = memif_msg_receive_disconnect (c, &msg)) != MEMIF_ERR_SUCCESS)
804  return err;
805  break;
806 
807  default:
808  return MEMIF_ERR_UNKNOWN_MSG;;
809  break;
810  }
811 
812  if (c != NULL)
813  c->flags |= MEMIF_CONNECTION_FLAG_WRITE;
814 /* libmemif_main_t *lm = &libmemif_main;
815  lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD); */
816  return MEMIF_ERR_SUCCESS; /* 0 */
817 }
818 
819 int
821 {
822  DBG ("connection fd error");
823  strncpy ((char *) c->remote_disconnect_string, "connection fd error", 19);
824  int err = memif_disconnect_internal (c);
825  return err;
826 }
827 
828 /* calls memif_msg_receive to handle pending messages on socket */
829 int
831 {
832  int err;
833  err = memif_msg_receive (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 {
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  libmemif_main_t *lm = &libmemif_main;
861 
862  lm->control_fd_update (c->fd,
863  MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_WRITE | MEMIF_FD_EVENT_MOD);
864 */
865  err = memif_msg_send (c->fd, &e->msg, e->fd);
866  lm->free (e);
867  goto done;
868 
869 done:
870  return err;
871 }
872 
873 int
875 {
876  int addr_len;
877  struct sockaddr_un client;
878  int conn_fd;
880 
881  DBG ("accept called");
882 
883  addr_len = sizeof (client);
884  conn_fd =
885  accept (ms->fd, (struct sockaddr *) &client, (socklen_t *) & addr_len);
886 
887  if (conn_fd < 0)
888  {
889  return memif_syscall_error_handler (errno);
890  }
891  DBG ("accept fd %d", ms->fd);
892  DBG ("conn fd %d", conn_fd);
893 
894  memif_list_elt_t elt;
895  elt.key = conn_fd;
896  elt.data_struct = ms;
897 
898  add_list_elt (&elt, &lm->pending_list, &lm->pending_list_len);
900 
901  return memif_msg_send_hello (conn_fd);
902 }
903 
904 int
906 {
907  int err;
908  DBG ("call recv");
909  err = memif_msg_receive (fd);
910  DBG ("recv finished");
911  return err;
912 }
static_fn int memif_msg_receive_disconnect(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:644
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:843
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
uint8_t string[96]
Definition: memif.h:122
#define MEMIF_SLAVE_ERR
Definition: socket.h:26
#define NULL
Definition: clib.h:57
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:830
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:1111
#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
memset(h->entries, 0, sizeof(h->entries[0])*entries)
#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:120
#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:581
#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:905
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:519
static_fn int memif_msg_receive(int ifd)
Definition: socket.c:660
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:118
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:616
int memif_conn_fd_error(memif_connection_t *c)
Definition: socket.c:820
int memif_connect1(memif_connection_t *c)
Definition: main.c:1305
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:119
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