FD.io VPP  v18.01.2-1-g9b554f3
Vector Packet Processing
memif.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 
19 #define _GNU_SOURCE
20 #include <stdint.h>
21 #include <net/if.h>
22 #include <sys/types.h>
23 #include <fcntl.h>
24 #include <sys/ioctl.h>
25 #include <sys/socket.h>
26 #include <sys/un.h>
27 #include <sys/uio.h>
28 #include <sys/mman.h>
29 #include <sys/prctl.h>
30 #include <sys/eventfd.h>
31 #include <inttypes.h>
32 #include <limits.h>
33 
34 #include <vlib/vlib.h>
35 #include <vlib/unix/unix.h>
36 #include <vppinfra/linux/syscall.h>
37 #include <vnet/plugin/plugin.h>
38 #include <vnet/ethernet/ethernet.h>
39 #include <vpp/app/version.h>
40 #include <memif/memif.h>
41 #include <memif/private.h>
42 
44 
45 static u32
47 {
48  /* nothing for now */
49  return 0;
50 }
51 
52 static void
54 {
55  if (mq->int_clib_file_index != ~0)
56  {
58  mq->int_clib_file_index = ~0;
59  mq->int_fd = -1;
60  }
61  else if (mq->int_fd > -1)
62  {
63  close (mq->int_fd);
64  mq->int_fd = -1;
65  }
66 }
67 
68 void
70 {
71  memif_main_t *mm = &memif_main;
72  vnet_main_t *vnm = vnet_get_main ();
73  memif_region_t *mr;
74  memif_queue_t *mq;
75  int i;
76 
77  if (mif == 0)
78  return;
79 
80  DBG ("disconnect %u (%v)", mif->dev_instance, err ? err->what : 0);
81 
82  if (err)
83  {
84  clib_error_t *e = 0;
85  mif->local_disc_string = vec_dup (err->what);
86  if (mif->sock && clib_socket_is_connected (mif->sock))
87  e = memif_msg_send_disconnect (mif, err);
88  clib_error_free (e);
89  }
90 
91  /* set interface down */
92  mif->flags &= ~(MEMIF_IF_FLAG_CONNECTED | MEMIF_IF_FLAG_CONNECTING);
93  if (mif->hw_if_index != ~0)
95 
96  /* close connection socket */
97  if (mif->sock && mif->sock->fd)
98  {
100  mif->socket_file_index);
101  hash_unset (msf->dev_instance_by_fd, mif->sock->fd);
102  memif_socket_close (&mif->sock);
103  }
104  else if (mif->sock)
105  {
106  clib_error_t *err;
107  err = clib_socket_close (mif->sock);
108  if (err)
109  clib_error_report (err);
110  clib_mem_free (mif->sock);
111  }
112 
113  vec_foreach_index (i, mif->rx_queues)
114  {
115  mq = vec_elt_at_index (mif->rx_queues, i);
116  if (mq->ring)
117  {
118  int rv;
120  if (rv)
121  DBG ("Warning: unable to unassign interface %d, "
122  "queue %d: rc=%d", mif->hw_if_index, i, rv);
123  mq->ring = 0;
124  }
125  }
126 
127  /* free tx and rx queues */
129  vec_free (mif->rx_queues);
130 
132  vec_free (mif->tx_queues);
133 
134  /* free memory regions */
135  vec_foreach (mr, mif->regions)
136  {
137  int rv;
138  if ((rv = munmap (mr->shm, mr->region_size)))
139  clib_warning ("munmap failed, rv = %d", rv);
140  if (mr->fd > -1)
141  close (mr->fd);
142  }
143  vec_free (mif->regions);
144  vec_free (mif->remote_name);
145  vec_free (mif->remote_if_name);
146  clib_fifo_free (mif->msg_queue);
147 }
148 
149 static clib_error_t *
151 {
152  memif_main_t *mm = &memif_main;
153  vnet_main_t *vnm = vnet_get_main ();
154  u16 qid = uf->private_data & 0xFFFF;
155  memif_if_t *mif = vec_elt_at_index (mm->interfaces, uf->private_data >> 16);
156  memif_queue_t *mq = vec_elt_at_index (mif->rx_queues, qid);
157  u64 b;
158  ssize_t size;
159 
160  size = read (uf->file_descriptor, &b, sizeof (b));
161  if (size < 0)
162  {
163  DBG_UNIX_LOG ("Failed to read from socket");
164  return 0;
165  }
166 
168  mq->int_count++;
169 
170  return 0;
171 }
172 
173 
174 clib_error_t *
176 {
177  vnet_main_t *vnm = vnet_get_main ();
178  clib_file_t template = { 0 };
179  memif_region_t *mr;
180  int i;
181 
182  DBG ("connect %u", mif->dev_instance);
183 
186 
187  vec_foreach (mr, mif->regions)
188  {
189  if (mr->shm)
190  continue;
191 
192  if (mr->fd < 0)
193  clib_error_return (0, "no memory region fd");
194 
195  if ((mr->shm = mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
196  MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
197  return clib_error_return_unix (0, "mmap");
198  }
199 
200  template.read_function = memif_int_fd_read_ready;
201 
202  vec_foreach_index (i, mif->tx_queues)
203  {
204  memif_queue_t *mq = vec_elt_at_index (mif->tx_queues, i);
205 
206  mq->ring = mif->regions[mq->region].shm + mq->offset;
207  if (mq->ring->cookie != MEMIF_COOKIE)
208  return clib_error_return (0, "wrong cookie on tx ring %u", i);
209  }
210 
211  vec_foreach_index (i, mif->rx_queues)
212  {
213  memif_queue_t *mq = vec_elt_at_index (mif->rx_queues, i);
214  int rv;
215 
216  mq->ring = mif->regions[mq->region].shm + mq->offset;
217  if (mq->ring->cookie != MEMIF_COOKIE)
218  return clib_error_return (0, "wrong cookie on tx ring %u", i);
219 
220  if (mq->int_fd > -1)
221  {
222  template.file_descriptor = mq->int_fd;
223  template.private_data = (mif->dev_instance << 16) | (i & 0xFFFF);
224  memif_file_add (&mq->int_clib_file_index, &template);
225  }
227  rv = vnet_hw_interface_set_rx_mode (vnm, mif->hw_if_index, i,
229  if (rv)
231  ("Warning: unable to set rx mode for interface %d queue %d: "
232  "rc=%d", mif->hw_if_index, i, rv);
233  else
234  {
236  vnet_hw_interface_get_rx_mode (vnm, mif->hw_if_index, i, &rxmode);
237 
238  if (rxmode == VNET_HW_INTERFACE_RX_MODE_POLLING)
240  }
241  }
242 
243  mif->flags &= ~MEMIF_IF_FLAG_CONNECTING;
244  mif->flags |= MEMIF_IF_FLAG_CONNECTED;
245 
248  return 0;
249 }
250 
253 {
254  if (vec_len (mif->regions) == 0)
255  return NULL;
256  void *p = mif->regions[0].shm;
257  int ring_size =
258  sizeof (memif_ring_t) +
259  sizeof (memif_desc_t) * (1 << mif->run.log2_ring_size);
260  p += (ring_num + type * mif->run.num_s2m_rings) * ring_size;
261 
262  return (memif_ring_t *) p;
263 }
264 
265 clib_error_t *
267 {
268  memif_ring_t *ring = NULL;
269  int i, j;
270  u64 buffer_offset;
271  memif_region_t *r;
272  clib_mem_vm_alloc_t alloc = { 0 };
273  clib_error_t *err;
274 
276  r = vec_elt_at_index (mif->regions, 0);
277 
278  buffer_offset = (mif->run.num_s2m_rings + mif->run.num_m2s_rings) *
279  (sizeof (memif_ring_t) +
280  sizeof (memif_desc_t) * (1 << mif->run.log2_ring_size));
281 
282  r->region_size = buffer_offset +
283  mif->run.buffer_size * (1 << mif->run.log2_ring_size) *
284  (mif->run.num_s2m_rings + mif->run.num_m2s_rings);
285 
286  alloc.name = "memif region";
287  alloc.size = r->region_size;
288  alloc.flags = CLIB_MEM_VM_F_SHARED;
289 
290  err = clib_mem_vm_ext_alloc (&alloc);
291  if (err)
292  return err;
293 
294  r->fd = alloc.fd;
295  r->shm = alloc.addr;
296 
297  for (i = 0; i < mif->run.num_s2m_rings; i++)
298  {
299  ring = memif_get_ring (mif, MEMIF_RING_S2M, i);
300  ring->head = ring->tail = 0;
301  ring->cookie = MEMIF_COOKIE;
302  for (j = 0; j < (1 << mif->run.log2_ring_size); j++)
303  {
304  u16 slot = i * (1 << mif->run.log2_ring_size) + j;
305  ring->desc[j].region = 0;
306  ring->desc[j].offset =
307  buffer_offset + (u32) (slot * mif->run.buffer_size);
308  ring->desc[j].buffer_length = mif->run.buffer_size;
309  }
310  }
311  for (i = 0; i < mif->run.num_m2s_rings; i++)
312  {
313  ring = memif_get_ring (mif, MEMIF_RING_M2S, i);
314  ring->head = ring->tail = 0;
315  ring->cookie = MEMIF_COOKIE;
316  for (j = 0; j < (1 << mif->run.log2_ring_size); j++)
317  {
318  u16 slot =
319  (i + mif->run.num_s2m_rings) * (1 << mif->run.log2_ring_size) + j;
320  ring->desc[j].region = 0;
321  ring->desc[j].offset =
322  buffer_offset + (u32) (slot * mif->run.buffer_size);
323  ring->desc[j].buffer_length = mif->run.buffer_size;
324  }
325  }
326 
327  ASSERT (mif->tx_queues == 0);
330  vec_foreach_index (i, mif->tx_queues)
331  {
332  memif_queue_t *mq = vec_elt_at_index (mif->tx_queues, i);
333  if ((mq->int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
334  return clib_error_return_unix (0, "eventfd[tx queue %u]", i);
335  mq->int_clib_file_index = ~0;
336  mq->ring = memif_get_ring (mif, MEMIF_RING_S2M, i);
337  mq->log2_ring_size = mif->cfg.log2_ring_size;
338  mq->region = 0;
339  mq->offset = (void *) mq->ring - (void *) mif->regions[mq->region].shm;
340  mq->last_head = 0;
341  mq->type = MEMIF_RING_S2M;
342  }
343 
344  ASSERT (mif->rx_queues == 0);
347  vec_foreach_index (i, mif->rx_queues)
348  {
349  memif_queue_t *mq = vec_elt_at_index (mif->rx_queues, i);
350  if ((mq->int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
351  return clib_error_return_unix (0, "eventfd[rx queue %u]", i);
352  mq->int_clib_file_index = ~0;
353  mq->ring = memif_get_ring (mif, MEMIF_RING_M2S, i);
354  mq->log2_ring_size = mif->cfg.log2_ring_size;
355  mq->region = 0;
356  mq->offset = (void *) mq->ring - (void *) mif->regions[mq->region].shm;
357  mq->last_head = 0;
358  mq->type = MEMIF_RING_M2S;
359  }
360 
361  return 0;
362 }
363 
364 static uword
366 {
367  memif_main_t *mm = &memif_main;
368  memif_if_t *mif;
369  clib_socket_t *sock;
370  uword *event_data = 0, event_type;
371  u8 enabled = 0;
372  f64 start_time, last_run_duration = 0, now;
373  clib_error_t *err;
374 
375  sock = clib_mem_alloc (sizeof (clib_socket_t));
376  memset (sock, 0, sizeof (clib_socket_t));
377 
378  while (1)
379  {
380  if (enabled)
382  last_run_duration);
383  else
385 
386  event_type = vlib_process_get_events (vm, &event_data);
387  vec_reset_length (event_data);
388 
389  switch (event_type)
390  {
391  case ~0:
392  break;
394  enabled = 1;
395  break;
397  enabled = 0;
398  continue;
399  default:
400  ASSERT (0);
401  }
402 
403  last_run_duration = start_time = vlib_time_now (vm);
404  /* *INDENT-OFF* */
405  pool_foreach (mif, mm->interfaces,
406  ({
407  memif_socket_file_t * msf = vec_elt_at_index (mm->socket_files, mif->socket_file_index);
408  /* Allow no more than 10us without a pause */
409  now = vlib_time_now (vm);
410  if (now > start_time + 10e-6)
411  {
412  vlib_process_suspend (vm, 100e-6); /* suspend for 100 us */
413  start_time = vlib_time_now (vm);
414  }
415 
416  if ((mif->flags & MEMIF_IF_FLAG_ADMIN_UP) == 0)
417  continue;
418 
419  if (mif->flags & MEMIF_IF_FLAG_CONNECTING)
420  continue;
421 
422  if (mif->flags & MEMIF_IF_FLAG_CONNECTED)
423  continue;
424 
425  if (mif->flags & MEMIF_IF_FLAG_IS_SLAVE)
426  {
427  memset (sock, 0, sizeof(clib_socket_t));
428  sock->config = (char *) msf->filename;
429  sock->flags = CLIB_SOCKET_F_IS_CLIENT| CLIB_SOCKET_F_SEQPACKET;
430 
431  if ((err = clib_socket_init (sock)))
432  {
433  clib_error_free (err);
434  }
435  else
436  {
437  clib_file_t t = { 0 };
438 
439  t.read_function = memif_slave_conn_fd_read_ready;
440  t.write_function = memif_slave_conn_fd_write_ready;
441  t.error_function = memif_slave_conn_fd_error;
442  t.file_descriptor = sock->fd;
443  t.private_data = mif->dev_instance;
444  memif_file_add (&sock->private_data, &t);
445  hash_set (msf->dev_instance_by_fd, sock->fd, mif->dev_instance);
446 
447  mif->flags |= MEMIF_IF_FLAG_CONNECTING;
448  mif->sock = sock;
449  sock = clib_mem_alloc (sizeof(clib_socket_t));
450  }
451  }
452  }));
453  /* *INDENT-ON* */
454  last_run_duration = vlib_time_now (vm) - last_run_duration;
455  }
456  return 0;
457 }
458 
459 /* *INDENT-OFF* */
461  .function = memif_process,
462  .type = VLIB_NODE_TYPE_PROCESS,
463  .name = "memif-process",
464 };
465 /* *INDENT-ON* */
466 
467 int
469 {
470  vnet_main_t *vnm = vnet_get_main ();
471  memif_main_t *mm = &memif_main;
472  memif_socket_file_t *msf =
474  clib_error_t *err;
475 
476  mif->flags |= MEMIF_IF_FLAG_DELETING;
479 
480  /* bring down the interface */
483 
484  err = clib_error_return (0, "interface deleted");
485  memif_disconnect (mif, err);
486  clib_error_free (err);
487 
488  if (mif->hw_if_index != ~0)
489  {
490  /* remove the interface */
491  if (mif->mode == MEMIF_INTERFACE_MODE_IP)
493  else
495  mif->hw_if_index = ~0;
496  }
497 
498  /* free interface data structures */
499  clib_spinlock_free (&mif->lockp);
500  mhash_unset (&msf->dev_instance_by_id, &mif->id, 0);
501 
502  /* remove socket file */
503  if (--(msf->ref_cnt) == 0)
504  {
505  if (msf->is_listener)
506  {
507  int i;
509  {
511  }
512  memif_socket_close (&msf->sock);
513  vec_free (msf->pending_clients);
514  }
518  vec_free (msf->filename);
519  if (msf->sock)
520  {
521  err = clib_socket_close (msf->sock);
522  if (err)
523  clib_error_report (err);
524  clib_mem_free (msf->sock);
525  }
526  pool_put (mm->socket_files, msf);
527  }
528 
529  memset (mif, 0, sizeof (*mif));
530  pool_put (mm->interfaces, mif);
531 
532  if (pool_elts (mm->interfaces) == 0)
535 
536  return 0;
537 }
538 
539 /* *INDENT-OFF* */
540 VNET_HW_INTERFACE_CLASS (memif_ip_hw_if_class, static) =
541 {
542  .name = "memif-ip",
544 };
545 /* *INDENT-ON* */
546 
547 int
549 {
550  memif_main_t *mm = &memif_main;
552  vnet_main_t *vnm = vnet_get_main ();
553  memif_if_t *mif = 0;
555  clib_error_t *error = 0;
556  int ret = 0;
557  uword *p;
559  memif_socket_file_t *msf = 0;
560  u8 *socket_filename;
561  int rv = 0;
562 
563  if (args->socket_filename == 0 || args->socket_filename[0] != '/')
564  {
565  clib_error_t *error;
567  if (error)
568  {
569  clib_error_free (error);
570  return VNET_API_ERROR_SYSCALL_ERROR_1;
571  }
572 
573  if (args->socket_filename == 0)
574  socket_filename = format (0, "%s/%s%c", vlib_unix_get_runtime_dir (),
576  else
577  socket_filename = format (0, "%s/%s%c", vlib_unix_get_runtime_dir (),
578  args->socket_filename, 0);
579 
580  }
581  else
582  socket_filename = vec_dup (args->socket_filename);
583 
584  p = mhash_get (&mm->socket_file_index_by_filename, socket_filename);
585 
586  if (p)
587  {
588  msf = vec_elt_at_index (mm->socket_files, p[0]);
589 
590  /* existing socket file can be either master or slave but cannot be both */
591  if (!msf->is_listener != !args->is_master)
592  {
593  rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
594  goto done;
595  }
596 
597  p = mhash_get (&msf->dev_instance_by_id, &args->id);
598  if (p)
599  {
600  rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
601  goto done;
602  }
603  }
604 
605  /* Create new socket file */
606  if (msf == 0)
607  {
608  struct stat file_stat;
609  /* If we are creating listener make sure file doesn't exist or if it
610  * exists thn delete it if it is old socket file */
611  if (args->is_master &&
612  (stat ((char *) socket_filename, &file_stat) == 0))
613  {
614  if (S_ISSOCK (file_stat.st_mode))
615  {
616  unlink ((char *) socket_filename);
617  }
618  else
619  {
620  error = clib_error_return (0, "File exists for %s",
621  socket_filename);
622  clib_error_report (error);
623  rv = VNET_API_ERROR_VALUE_EXIST;
624  goto done;
625  }
626  }
627  pool_get (mm->socket_files, msf);
628  memset (msf, 0, sizeof (memif_socket_file_t));
629  mhash_init (&msf->dev_instance_by_id, sizeof (uword),
630  sizeof (memif_interface_id_t));
631  msf->dev_instance_by_fd = hash_create (0, sizeof (uword));
632  msf->filename = socket_filename;
633  msf->is_listener = (args->is_master != 0);
634  socket_filename = 0;
636  msf - mm->socket_files, 0);
637  DBG ("creating socket file %s", msf->filename);
638  }
639 
640  pool_get (mm->interfaces, mif);
641  memset (mif, 0, sizeof (*mif));
642  mif->dev_instance = mif - mm->interfaces;
643  mif->socket_file_index = msf - mm->socket_files;
644  mif->id = args->id;
645  mif->sw_if_index = mif->hw_if_index = mif->per_interface_next_index = ~0;
646  mif->mode = args->mode;
647  if (args->secret)
648  mif->secret = vec_dup (args->secret);
649 
650  if (tm->n_vlib_mains > 1)
651  clib_spinlock_init (&mif->lockp);
652 
653 
655  {
656 
657  if (!args->hw_addr_set)
658  {
659  f64 now = vlib_time_now (vm);
660  u32 rnd;
661  rnd = (u32) (now * 1e6);
662  rnd = random_u32 (&rnd);
663 
664  memcpy (args->hw_addr + 2, &rnd, sizeof (rnd));
665  args->hw_addr[0] = 2;
666  args->hw_addr[1] = 0xfe;
667  }
669  mif->dev_instance, args->hw_addr,
670  &mif->hw_if_index,
672  }
673  else if (mif->mode == MEMIF_INTERFACE_MODE_IP)
674  {
675  mif->hw_if_index =
677  mif->dev_instance,
678  memif_ip_hw_if_class.index,
679  mif->dev_instance);
680  }
681  else
682  error = clib_error_return (0, "unsupported interface mode");
683 
684  if (error)
685  {
686  clib_error_report (error);
687  ret = VNET_API_ERROR_SYSCALL_ERROR_2;
688  goto error;
689  }
690 
691  sw = vnet_get_hw_sw_interface (vnm, mif->hw_if_index);
692  mif->sw_if_index = sw->sw_if_index;
693 
694  mif->cfg.log2_ring_size = args->log2_ring_size;
695  mif->cfg.buffer_size = args->buffer_size;
696  mif->cfg.num_s2m_rings =
697  args->is_master ? args->rx_queues : args->tx_queues;
698  mif->cfg.num_m2s_rings =
699  args->is_master ? args->tx_queues : args->rx_queues;
700 
701  args->sw_if_index = mif->sw_if_index;
702 
703  /* If this is new one, start listening */
704  if (msf->is_listener && msf->ref_cnt == 0)
705  {
706  struct stat file_stat;
708 
709  ASSERT (msf->sock == 0);
710  msf->sock = s;
711 
712  memset (s, 0, sizeof (clib_socket_t));
713  s->config = (char *) msf->filename;
714  s->flags = CLIB_SOCKET_F_IS_SERVER |
717 
718  if ((error = clib_socket_init (s)))
719  {
720  clib_error_report (error);
721  ret = VNET_API_ERROR_SYSCALL_ERROR_4;
722  goto error;
723  }
724 
725  if (stat ((char *) msf->filename, &file_stat) == -1)
726  {
727  ret = VNET_API_ERROR_SYSCALL_ERROR_8;
728  goto error;
729  }
730 
731  clib_file_t template = { 0 };
733  template.file_descriptor = msf->sock->fd;
734  template.private_data = mif->socket_file_index;
735  memif_file_add (&msf->sock->private_data, &template);
736  }
737 
738  msf->ref_cnt++;
739 
740  if (args->is_master == 0)
741  mif->flags |= MEMIF_IF_FLAG_IS_SLAVE;
742 
743  hw = vnet_get_hw_interface (vnm, mif->hw_if_index);
746  memif_input_node.index);
747 
748  mhash_set (&msf->dev_instance_by_id, &mif->id, mif->dev_instance, 0);
749 
750  if (pool_elts (mm->interfaces) == 1)
751  {
754  }
755  goto done;
756 
757 error:
758  if (mif->hw_if_index != ~0)
759  {
760  if (mif->mode == MEMIF_INTERFACE_MODE_IP)
762  else
764  mif->hw_if_index = ~0;
765  }
766  memif_delete_if (vm, mif);
767  return ret;
768 
769 done:
770  vec_free (socket_filename);
771  return rv;
772 }
773 
774 
775 static clib_error_t *
777 {
778  memif_main_t *mm = &memif_main;
780 
781  memset (mm, 0, sizeof (memif_main_t));
782 
783  /* initialize binary API */
785 
787 
790 
791  return 0;
792 }
793 
795 
796 /* *INDENT-OFF* */
798  .version = VPP_BUILD_VER,
799  .description = "Packet Memory Interface (experimetal)",
800 };
801 /* *INDENT-ON* */
802 
803 /*
804  * fd.io coding-style-patch-verification: ON
805  *
806  * Local Variables:
807  * eval: (c-set-style "gnu")
808  * End:
809  */
#define DBG_UNIX_LOG(...)
memif_if_t * interfaces
Definition: private.h:184
vmrglw vmrglh hi
#define vec_foreach_index(var, v)
Iterate over vector indices.
#define hash_set(h, key, value)
Definition: hash.h:254
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:538
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Definition: node_funcs.h:699
#define hash_unset(h, key)
Definition: hash.h:260
u8 * secret
Definition: private.h:144
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:619
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:322
clib_socket_t ** pending_clients
Definition: private.h:69
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static uword clib_socket_is_connected(clib_socket_t *sock)
Definition: socket.h:112
mhash_t socket_file_index_by_filename
Definition: private.h:188
memif_socket_file_t * socket_files
Definition: private.h:187
memif_log2_ring_size_t log2_ring_size
Definition: private.h:157
#define NULL
Definition: clib.h:55
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
Definition: mhash.c:353
struct memif_if_t::@366 run
void * addr
Pointer to allocated memory, set on successful allocation.
Definition: mem.h:344
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:224
struct memif_if_t::@365 cfg
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
u32 file_descriptor
Definition: file.h:53
static clib_error_t * memif_init(vlib_main_t *vm)
Definition: memif.c:776
clib_error_t * clib_socket_init(clib_socket_t *s)
Definition: socket.c:376
clib_error_t * memif_msg_send_disconnect(memif_if_t *mif, clib_error_t *err)
Definition: socket.c:189
memif_interface_mode_t mode
Definition: private.h:211
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:394
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:443
u8 num_m2s_rings
Definition: private.h:159
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:225
#define memif_file_del_by_index(a)
Definition: private.h:62
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
clib_file_function_t * read_function
Definition: file.h:63
static void clib_spinlock_free(clib_spinlock_t *p)
Definition: lock.h:40
uint32_t buffer_length
Definition: memif.h:151
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define CLIB_SOCKET_F_IS_SERVER
Definition: socket.h:58
vnet_hw_interface_rx_mode
Definition: interface.h:51
#define static_always_inline
Definition: clib.h:93
clib_error_t * clib_mem_vm_ext_alloc(clib_mem_vm_alloc_t *a)
Definition: mem.c:58
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:438
u8 * remote_name
Definition: private.h:152
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
Definition: node_funcs.h:542
clib_error_t * memif_plugin_api_hookup(vlib_main_t *vm)
Definition: memif_api.c:311
uword socket_file_index
Definition: private.h:142
static char * vlib_unix_get_runtime_dir(void)
Definition: unix.h:138
uint32_t cookie
Definition: memif.h:167
char * name
Name for memory allocation, set by caller.
Definition: mem.h:341
clib_error_t * memif_init_regions_and_queues(memif_if_t *mif)
Definition: memif.c:266
static_always_inline void vnet_device_input_set_interrupt_pending(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.h:136
u16 buffer_size
Definition: private.h:160
memif_log2_ring_size_t log2_ring_size
Definition: private.h:212
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
vnet_device_class_t memif_device_class
u32 per_interface_next_index
Definition: private.h:138
#define clib_error_return(e, args...)
Definition: error.h:99
memif_region_offset_t offset
Definition: private.h:99
unsigned long u64
Definition: types.h:89
uword size
Allocation size, set by caller.
Definition: mem.h:342
#define memif_file_add(a, b)
Definition: private.h:58
u32 vnet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u32 hw_class_index, u32 hw_instance)
Definition: interface.c:689
static u32 memif_eth_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
Definition: memif.c:46
mhash_t dev_instance_by_id
Definition: private.h:74
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:33
#define CLIB_MEM_VM_F_SHARED
Definition: mem.h:326
memif_region_index_t region
Definition: memif.h:150
u16 last_head
Definition: private.h:101
vlib_node_registration_t memif_input_node
(constructor) VLIB_REGISTER_NODE (memif_input_node)
Definition: node.c:575
memif_desc_t desc[0]
Definition: memif.h:174
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:950
int memif_delete_if(vlib_main_t *vm, memif_if_t *mif)
Definition: memif.c:468
int fd
File desriptor, set on successful allocation if CLIB_MEM_VM_F_SHARED is set.
Definition: mem.h:345
uword dev_instance
Definition: private.h:135
static clib_error_t * clib_socket_close(clib_socket_t *sock)
Definition: socket.h:175
clib_spinlock_t lockp
Definition: private.h:130
#define clib_error_return_unix(e, args...)
Definition: error.h:102
int vnet_hw_interface_get_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, vnet_hw_interface_rx_mode *mode)
Definition: devices.c:312
#define hash_free(h)
Definition: hash.h:309
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:271
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:370
memif_interface_id_t id
Definition: private.h:207
int memif_create_if(vlib_main_t *vm, memif_create_if_args_t *args)
Definition: memif.c:548
uword int_clib_file_index
Definition: private.h:106
#define VNET_HW_INTERFACE_FLAG_SUPPORTS_INT_MODE
Definition: interface.h:420
VNET_HW_INTERFACE_CLASS(memif_ip_hw_if_class, static)
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
Definition: mhash.h:117
memif_queue_t * tx_queues
Definition: private.h:149
clib_error_t * memif_connect(memif_if_t *mif)
Definition: memif.c:175
static void mhash_init_c_string(mhash_t *h, uword n_value_bytes)
Definition: mhash.h:78
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
Definition: mhash.c:168
vlib_main_t * vm
Definition: buffer.c:283
u8 * local_disc_string
Definition: private.h:172
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
#define clib_warning(format, args...)
Definition: error.h:59
#define DBG(...)
uint32_t memif_interface_id_t
Definition: memif.h:64
void memif_disconnect(memif_if_t *mif, clib_error_t *err)
Definition: memif.c:69
u32 flags
vm allocation flags: CLIB_MEM_VM_F_SHARED: request shared memory, file destiptor will be provided o...
Definition: mem.h:331
memif_ring_type_t type
Definition: private.h:110
memif_region_t * regions
Definition: private.h:146
#define hash_create(elts, value_bytes)
Definition: hash.h:681
u32 ** rx_buffers
Definition: private.h:191
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
void vnet_hw_interface_assign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, uword thread_index)
Definition: devices.c:138
static uword * mhash_get(mhash_t *h, const void *key)
Definition: mhash.h:110
static void memif_queue_intfd_close(memif_queue_t *mq)
Definition: memif.c:53
static void mhash_free(mhash_t *h)
Definition: mhash.h:149
static clib_error_t * memif_int_fd_read_ready(clib_file_t *uf)
Definition: memif.c:150
u32 flags
Definition: private.h:131
memif_ring_t * ring
Definition: private.h:96
u64 size
Definition: vhost-user.h:76
static void clib_mem_free(void *p)
Definition: mem.h:179
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
Definition: interface.c:273
#define clib_error_report(e)
Definition: error.h:113
u32 hw_if_index
Definition: private.h:133
struct _socket_t clib_socket_t
clib_error_t * memif_slave_conn_fd_write_ready(clib_file_t *uf)
Definition: socket.c:573
#define clib_fifo_free(f)
Definition: fifo.h:257
#define MEMIF_RING_FLAG_MASK_INT
Definition: memif.h:169
static void * clib_mem_alloc(uword size)
Definition: mem.h:112
clib_error_t * memif_slave_conn_fd_error(clib_file_t *uf)
Definition: socket.c:581
#define CLIB_SOCKET_F_SEQPACKET
Definition: socket.h:63
clib_error_t * memif_slave_conn_fd_read_ready(clib_file_t *uf)
Definition: socket.c:530
u64 int_count
Definition: private.h:107
void vnet_delete_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:899
u64 uword
Definition: types.h:112
memif_region_offset_t offset
Definition: memif.h:154
uword * dev_instance_by_fd
Definition: private.h:77
u8 num_s2m_rings
Definition: private.h:158
VLIB_PLUGIN_REGISTER()
clib_error_t * vlib_unix_recursive_mkdir(char *path)
Definition: util.c:102
unsigned short u16
Definition: types.h:57
static_always_inline memif_ring_t * memif_get_ring(memif_if_t *mif, memif_ring_type_t type, u16 ring_num)
Definition: memif.c:252
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
#define MEMIF_DEFAULT_SOCKET_FILENAME
Definition: private.h:20
#define CLIB_SOCKET_F_PASSCRED
Definition: socket.h:64
a point 2 point interface
Definition: interface.h:289
void memif_socket_close(clib_socket_t **sock)
Definition: socket.c:43
#define clib_error_free(e)
Definition: error.h:86
void * shm
Definition: private.h:82
u8 * remote_if_name
Definition: private.h:153
memif_interface_id_t id
Definition: private.h:132
memif_log2_ring_size_t log2_ring_size
Definition: private.h:97
int vnet_hw_interface_unassign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.c:187
static u32 random_u32(u32 *seed)
32-bit random number generator
Definition: random.h:69
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
uint16_t flags
Definition: memif.h:168
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
static vlib_node_registration_t memif_process_node
(constructor) VLIB_REGISTER_NODE (memif_process_node)
Definition: memif.c:460
u8 * remote_disc_string
Definition: private.h:173
memif_ring_type_t
Definition: memif.h:47
#define vec_foreach(var, vec)
Vector iterator.
volatile uint16_t head
Definition: memif.h:170
uword private_data
Definition: file.h:60
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:546
Definition: file.h:50
clib_socket_t * sock
Definition: private.h:141
memif_queue_t * rx_queues
Definition: private.h:148
int vnet_hw_interface_set_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, vnet_hw_interface_rx_mode mode)
Definition: devices.c:252
clib_error_t * memif_conn_fd_accept_ready(clib_file_t *uf)
Definition: socket.c:633
u32 flags
Definition: vhost-user.h:77
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
#define CLIB_SOCKET_F_ALLOW_GROUP_WRITE
Definition: socket.h:62
memif_msg_fifo_elt_t * msg_queue
Definition: private.h:143
memif_main_t memif_main
Definition: memif.c:43
memif_region_index_t region
Definition: private.h:98
clib_socket_t * sock
Definition: private.h:68
#define MEMIF_COOKIE
Definition: memif.h:25
u32 sw_if_index
Definition: private.h:134
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: devices.h:79
volatile uint16_t tail
Definition: memif.h:172
memif_interface_mode_t mode
Definition: private.h:136
static uword memif_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: memif.c:365
memif_region_size_t region_size
Definition: private.h:83
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128