FD.io VPP  v17.07.01-10-g3be13f0
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 <vnet/plugin/plugin.h>
37 #include <vnet/ethernet/ethernet.h>
38 #include <vpp/app/version.h>
39 #include <memif/memif.h>
40 #include <memif/private.h>
41 
43 
44 static u32
46 {
47  /* nothing for now */
48  return 0;
49 }
50 
51 static void
53 {
54  if (mq->int_unix_file_index != ~0)
55  {
57  mq->int_unix_file_index = ~0;
58  mq->int_fd = -1;
59  }
60  else if (mq->int_fd > -1)
61  {
62  close (mq->int_fd);
63  mq->int_fd = -1;
64  }
65 }
66 
67 void
69 {
70  memif_main_t *mm = &memif_main;
71  vnet_main_t *vnm = vnet_get_main ();
72  memif_region_t *mr;
73  memif_queue_t *mq;
74  int i;
75 
76  if (mif == 0)
77  return;
78 
79  DBG ("disconnect %u (%v)", mif->dev_instance, err ? err->what : 0);
80 
81  if (err)
82  {
83  clib_error_t *e = 0;
84  mif->local_disc_string = vec_dup (err->what);
85  if (mif->conn_fd > -1)
86  e = memif_msg_send_disconnect (mif, err);
87  clib_error_free (e);
88  }
89 
90  /* set interface down */
91  mif->flags &= ~(MEMIF_IF_FLAG_CONNECTED | MEMIF_IF_FLAG_CONNECTING);
92  if (mif->hw_if_index != ~0)
94 
95  /* close connection socket */
96  if (mif->conn_unix_file_index != ~0)
97  {
99  mif->socket_file_index);
102  mif->conn_unix_file_index = ~0;
103  }
104  else if (mif->conn_fd > -1)
105  close (mif->conn_fd);
106  mif->conn_fd = -1;
107 
108  vec_foreach_index (i, mif->rx_queues)
109  {
110  mq = vec_elt_at_index (mif->rx_queues, i);
111  if (mq->ring)
112  {
113  int rv;
115  if (rv)
116  DBG ("Warning: unable to unassign interface %d, "
117  "queue %d: rc=%d", mif->hw_if_index, i, rv);
118  mq->ring = 0;
119  }
120  }
121 
122  /* free tx and rx queues */
124  vec_free (mif->rx_queues);
125 
127  vec_free (mif->tx_queues);
128 
129  /* free memory regions */
130  vec_foreach (mr, mif->regions)
131  {
132  int rv;
133  if ((rv = munmap (mr->shm, mr->region_size)))
134  clib_warning ("munmap failed, rv = %d", rv);
135  if (mr->fd > -1)
136  close (mr->fd);
137  }
138  vec_free (mif->regions);
139 
140  mif->remote_pid = 0;
141  vec_free (mif->remote_name);
142  vec_free (mif->remote_if_name);
143  clib_fifo_free (mif->msg_queue);
144 }
145 
146 static clib_error_t *
148 {
149  memif_main_t *mm = &memif_main;
150  vnet_main_t *vnm = vnet_get_main ();
151  u16 qid = uf->private_data & 0xFFFF;
152  memif_if_t *mif = vec_elt_at_index (mm->interfaces, uf->private_data >> 16);
153  memif_queue_t *mq = vec_elt_at_index (mif->rx_queues, qid);
154  u64 b;
155  ssize_t size;
156 
157  size = read (uf->file_descriptor, &b, sizeof (b));
158  if (size < 0)
159  {
160  DBG_UNIX_LOG ("Failed to read from socket");
161  return 0;
162  }
163 
165  mq->int_count++;
166 
167  return 0;
168 }
169 
170 
171 clib_error_t *
173 {
174  vnet_main_t *vnm = vnet_get_main ();
175  unix_file_t template = { 0 };
176  memif_region_t *mr;
177  int i;
178 
179  DBG ("connect %u", mif->dev_instance);
180 
183 
184  vec_foreach (mr, mif->regions)
185  {
186  if (mr->shm)
187  continue;
188 
189  if (mr->fd < 0)
190  clib_error_return (0, "no memory region fd");
191 
192  if ((mr->shm = mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
193  MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
194  return clib_error_return_unix (0, "mmap");
195  }
196 
197  template.read_function = memif_int_fd_read_ready;
198 
199  vec_foreach_index (i, mif->tx_queues)
200  {
201  memif_queue_t *mq = vec_elt_at_index (mif->tx_queues, i);
202 
203  mq->ring = mif->regions[mq->region].shm + mq->offset;
204  if (mq->ring->cookie != MEMIF_COOKIE)
205  return clib_error_return (0, "wrong cookie on tx ring %u", i);
206  }
207 
208  vec_foreach_index (i, mif->rx_queues)
209  {
210  memif_queue_t *mq = vec_elt_at_index (mif->rx_queues, i);
211  int rv;
212 
213  mq->ring = mif->regions[mq->region].shm + mq->offset;
214  if (mq->ring->cookie != MEMIF_COOKIE)
215  return clib_error_return (0, "wrong cookie on tx ring %u", i);
216 
217  if (mq->int_fd > -1)
218  {
219  template.file_descriptor = mq->int_fd;
220  template.private_data = (mif->dev_instance << 16) | (i & 0xFFFF);
221  memif_file_add (&mq->int_unix_file_index, &template);
222  }
224  rv = vnet_hw_interface_set_rx_mode (vnm, mif->hw_if_index, i,
226  if (rv)
228  ("Warning: unable to set rx mode for interface %d queue %d: "
229  "rc=%d", mif->hw_if_index, i, rv);
230  else
231  {
233  vnet_hw_interface_get_rx_mode (vnm, mif->hw_if_index, i, &rxmode);
234 
235  if (rxmode == VNET_HW_INTERFACE_RX_MODE_POLLING)
237  }
238  }
239 
240  mif->flags &= ~MEMIF_IF_FLAG_CONNECTING;
241  mif->flags |= MEMIF_IF_FLAG_CONNECTED;
242 
245  return 0;
246 }
247 
250 {
251  if (vec_len (mif->regions) == 0)
252  return NULL;
253  void *p = mif->regions[0].shm;
254  int ring_size =
255  sizeof (memif_ring_t) +
256  sizeof (memif_desc_t) * (1 << mif->run.log2_ring_size);
257  p += (ring_num + type * mif->run.num_s2m_rings) * ring_size;
258 
259  return (memif_ring_t *) p;
260 }
261 
262 clib_error_t *
264 {
265  memif_ring_t *ring = NULL;
266  int i, j;
267  u64 buffer_offset;
268  memif_region_t *r;
269 
271  r = vec_elt_at_index (mif->regions, 0);
272 
273  buffer_offset = (mif->run.num_s2m_rings + mif->run.num_m2s_rings) *
274  (sizeof (memif_ring_t) +
275  sizeof (memif_desc_t) * (1 << mif->run.log2_ring_size));
276 
277  r->region_size = buffer_offset +
278  mif->run.buffer_size * (1 << mif->run.log2_ring_size) *
279  (mif->run.num_s2m_rings + mif->run.num_m2s_rings);
280 
281  if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
282  return clib_error_return_unix (0, "memfd_create");
283 
284  if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
285  return clib_error_return_unix (0, "fcntl (F_ADD_SEALS, F_SEAL_SHRINK)");
286 
287  if ((ftruncate (r->fd, r->region_size)) == -1)
288  return clib_error_return_unix (0, "ftruncate");
289 
290  if ((r->shm = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
291  MAP_SHARED, r->fd, 0)) == MAP_FAILED)
292  return clib_error_return_unix (0, "mmap");
293 
294  for (i = 0; i < mif->run.num_s2m_rings; i++)
295  {
296  ring = memif_get_ring (mif, MEMIF_RING_S2M, i);
297  ring->head = ring->tail = 0;
298  ring->cookie = MEMIF_COOKIE;
299  for (j = 0; j < (1 << mif->run.log2_ring_size); j++)
300  {
301  u16 slot = i * (1 << mif->run.log2_ring_size) + j;
302  ring->desc[j].region = 0;
303  ring->desc[j].offset =
304  buffer_offset + (u32) (slot * mif->run.buffer_size);
305  ring->desc[j].buffer_length = mif->run.buffer_size;
306  }
307  }
308  for (i = 0; i < mif->run.num_m2s_rings; i++)
309  {
310  ring = memif_get_ring (mif, MEMIF_RING_M2S, i);
311  ring->head = ring->tail = 0;
312  ring->cookie = MEMIF_COOKIE;
313  for (j = 0; j < (1 << mif->run.log2_ring_size); j++)
314  {
315  u16 slot =
316  (i + mif->run.num_s2m_rings) * (1 << mif->run.log2_ring_size) + j;
317  ring->desc[j].region = 0;
318  ring->desc[j].offset =
319  buffer_offset + (u32) (slot * mif->run.buffer_size);
320  ring->desc[j].buffer_length = mif->run.buffer_size;
321  }
322  }
323 
324  ASSERT (mif->tx_queues == 0);
327  vec_foreach_index (i, mif->tx_queues)
328  {
329  memif_queue_t *mq = vec_elt_at_index (mif->tx_queues, i);
330  if ((mq->int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
331  return clib_error_return_unix (0, "eventfd[tx queue %u]", i);
332  mq->int_unix_file_index = ~0;
333  mq->ring = memif_get_ring (mif, MEMIF_RING_S2M, i);
334  mq->log2_ring_size = mif->cfg.log2_ring_size;
335  mq->region = 0;
336  mq->offset = (void *) mq->ring - (void *) mif->regions[mq->region].shm;
337  mq->last_head = 0;
338  }
339 
340  ASSERT (mif->rx_queues == 0);
343  vec_foreach_index (i, mif->rx_queues)
344  {
345  memif_queue_t *mq = vec_elt_at_index (mif->rx_queues, i);
346  if ((mq->int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
347  return clib_error_return_unix (0, "eventfd[rx queue %u]", i);
348  mq->int_unix_file_index = ~0;
349  mq->ring = memif_get_ring (mif, MEMIF_RING_M2S, i);
350  mq->log2_ring_size = mif->cfg.log2_ring_size;
351  mq->region = 0;
352  mq->offset = (void *) mq->ring - (void *) mif->regions[mq->region].shm;
353  mq->last_head = 0;
354  }
355 
356  return 0;
357 }
358 
359 static uword
361 {
362  memif_main_t *mm = &memif_main;
363  memif_if_t *mif;
364  struct sockaddr_un sun;
365  int sockfd;
366  uword *event_data = 0, event_type;
367  u8 enabled = 0;
368  f64 start_time, last_run_duration = 0, now;
369 
370  sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
371  if (sockfd < 0)
372  {
373  DBG_UNIX_LOG ("socket AF_UNIX");
374  return 0;
375  }
376  sun.sun_family = AF_UNIX;
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  strncpy (sun.sun_path, (char *) msf->filename,
428  sizeof (sun.sun_path) - 1);
429 
430  if (connect
431  (sockfd, (struct sockaddr *) &sun,
432  sizeof (struct sockaddr_un)) == 0)
433  {
434  unix_file_t t = { 0 };
435 
436  mif->conn_fd = sockfd;
437  t.read_function = memif_slave_conn_fd_read_ready;
438  t.write_function = memif_slave_conn_fd_write_ready;
439  t.error_function = memif_slave_conn_fd_error;
440  t.file_descriptor = mif->conn_fd;
441  t.private_data = mif->dev_instance;
442  memif_file_add (&mif->conn_unix_file_index, &t);
443  hash_set (msf->dev_instance_by_fd, mif->conn_fd, mif->dev_instance);
444 
445  mif->flags |= MEMIF_IF_FLAG_CONNECTING;
446 
447  /* grab another fd */
448  sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
449  if (sockfd < 0)
450  {
451  DBG_UNIX_LOG ("socket AF_UNIX");
452  return 0;
453  }
454  }
455  }
456  }));
457  /* *INDENT-ON* */
458  last_run_duration = vlib_time_now (vm) - last_run_duration;
459  }
460  return 0;
461 }
462 
463 /* *INDENT-OFF* */
465  .function = memif_process,
466  .type = VLIB_NODE_TYPE_PROCESS,
467  .name = "memif-process",
468 };
469 /* *INDENT-ON* */
470 
471 int
473 {
474  vnet_main_t *vnm = vnet_get_main ();
475  memif_main_t *mm = &memif_main;
476  memif_socket_file_t *msf =
478  clib_error_t *err;
479 
480  mif->flags |= MEMIF_IF_FLAG_DELETING;
483 
484  /* bring down the interface */
487 
488  err = clib_error_return (0, "interface deleted");
489  memif_disconnect (mif, err);
490  clib_error_free (err);
491 
492  /* remove the interface */
493  if (mif->mode == MEMIF_INTERFACE_MODE_IP)
495  else
497  mif->hw_if_index = ~0;
498 
499  /* free interface data structures */
500  clib_spinlock_free (&mif->lockp);
501  mhash_unset (&msf->dev_instance_by_id, &mif->id, 0);
502 
503  /* remove socket file */
504  if (--(msf->ref_cnt) == 0)
505  {
506  if (msf->is_listener)
507  {
508  uword *x;
511  {
513  }
515  }
519  vec_free (msf->filename);
520  pool_put (mm->socket_files, msf);
521  }
522 
523  memset (mif, 0, sizeof (*mif));
524  pool_put (mm->interfaces, mif);
525 
526  if (pool_elts (mm->interfaces) == 0)
529 
530  return 0;
531 }
532 
533 /* *INDENT-OFF* */
534 VNET_HW_INTERFACE_CLASS (memif_ip_hw_if_class, static) =
535 {
536  .name = "memif-ip",
538 };
539 /* *INDENT-ON* */
540 
541 int
543 {
544  memif_main_t *mm = &memif_main;
546  vnet_main_t *vnm = vnet_get_main ();
547  memif_if_t *mif = 0;
549  clib_error_t *error = 0;
550  int ret = 0;
551  uword *p;
553  memif_socket_file_t *msf = 0;
554  u8 *socket_filename;
555  int rv = 0;
556 
557  if (args->socket_filename == 0 || args->socket_filename[0] != '/')
558  {
559  rv = mkdir (MEMIF_DEFAULT_SOCKET_DIR, 0755);
560  if (rv && errno != EEXIST)
561  return VNET_API_ERROR_SYSCALL_ERROR_1;
562 
563  if (args->socket_filename == 0)
564  socket_filename = format (0, "%s/%s%c", MEMIF_DEFAULT_SOCKET_DIR,
566  else
567  socket_filename = format (0, "%s/%s%c", MEMIF_DEFAULT_SOCKET_DIR,
568  args->socket_filename, 0);
569 
570  }
571  else
572  socket_filename = vec_dup (args->socket_filename);
573 
574  p = mhash_get (&mm->socket_file_index_by_filename, socket_filename);
575 
576  if (p)
577  {
578  msf = vec_elt_at_index (mm->socket_files, p[0]);
579 
580  /* existing socket file can be either master or slave but cannot be both */
581  if (!msf->is_listener != !args->is_master)
582  {
583  rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
584  goto done;
585  }
586 
587  p = mhash_get (&msf->dev_instance_by_id, &args->id);
588  if (p)
589  {
590  rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
591  goto done;
592  }
593  }
594 
595  /* Create new socket file */
596  if (msf == 0)
597  {
598  struct stat file_stat;
599  /* If we are creating listener make sure file doesn't exist or if it
600  * exists thn delete it if it is old socket file */
601  if (args->is_master &&
602  (stat ((char *) socket_filename, &file_stat) == 0))
603  {
604  if (S_ISSOCK (file_stat.st_mode))
605  {
606  unlink ((char *) socket_filename);
607  }
608  else
609  {
610  ret = VNET_API_ERROR_SYSCALL_ERROR_3;
611  goto error;
612  }
613  }
614  pool_get (mm->socket_files, msf);
615  memset (msf, 0, sizeof (memif_socket_file_t));
616  mhash_init (&msf->dev_instance_by_id, sizeof (uword),
617  sizeof (memif_interface_id_t));
618  msf->dev_instance_by_fd = hash_create (0, sizeof (uword));
619  msf->filename = socket_filename;
620  msf->fd = -1;
621  msf->is_listener = (args->is_master != 0);
622  socket_filename = 0;
624  msf - mm->socket_files, 0);
625  DBG ("creating socket file %s", msf->filename);
626  }
627 
628  pool_get (mm->interfaces, mif);
629  memset (mif, 0, sizeof (*mif));
630  mif->dev_instance = mif - mm->interfaces;
631  mif->socket_file_index = msf - mm->socket_files;
632  mif->id = args->id;
633  mif->sw_if_index = mif->hw_if_index = mif->per_interface_next_index = ~0;
634  mif->conn_unix_file_index = ~0;
635  mif->conn_fd = -1;
636  mif->mode = args->mode;
637  if (args->secret)
638  mif->secret = vec_dup (args->secret);
639 
640  if (tm->n_vlib_mains > 1)
641  clib_spinlock_init (&mif->lockp);
642 
643 
645  {
646 
647  if (!args->hw_addr_set)
648  {
649  f64 now = vlib_time_now (vm);
650  u32 rnd;
651  rnd = (u32) (now * 1e6);
652  rnd = random_u32 (&rnd);
653 
654  memcpy (args->hw_addr + 2, &rnd, sizeof (rnd));
655  args->hw_addr[0] = 2;
656  args->hw_addr[1] = 0xfe;
657  }
659  mif->dev_instance, args->hw_addr,
660  &mif->hw_if_index,
662  }
663  else if (mif->mode == MEMIF_INTERFACE_MODE_IP)
664  {
665  mif->hw_if_index =
667  mif->dev_instance,
668  memif_ip_hw_if_class.index,
669  mif->dev_instance);
670  }
671  else
672  error = clib_error_return (0, "unsupported interface mode");
673 
674  if (error)
675  {
676  clib_error_report (error);
677  ret = VNET_API_ERROR_SYSCALL_ERROR_2;
678  goto error;
679  }
680 
681  sw = vnet_get_hw_sw_interface (vnm, mif->hw_if_index);
682  mif->sw_if_index = sw->sw_if_index;
683 
684  mif->cfg.log2_ring_size = args->log2_ring_size;
685  mif->cfg.buffer_size = args->buffer_size;
686  mif->cfg.num_s2m_rings =
687  args->is_master ? args->rx_queues : args->tx_queues;
688  mif->cfg.num_m2s_rings =
689  args->is_master ? args->tx_queues : args->rx_queues;
690 
691  args->sw_if_index = mif->sw_if_index;
692 
693  /* If this is new one, start listening */
694  if (msf->is_listener && msf->ref_cnt == 0)
695  {
696  struct sockaddr_un un = { 0 };
697  struct stat file_stat;
698  int on = 1;
699 
700  if ((msf->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0)) < 0)
701  {
702  ret = VNET_API_ERROR_SYSCALL_ERROR_4;
703  goto error;
704  }
705 
706  un.sun_family = AF_UNIX;
707  strncpy ((char *) un.sun_path, (char *) msf->filename,
708  sizeof (un.sun_path) - 1);
709 
710  if (setsockopt (msf->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
711  {
712  ret = VNET_API_ERROR_SYSCALL_ERROR_5;
713  goto error;
714  }
715  if (bind (msf->fd, (struct sockaddr *) &un, sizeof (un)) == -1)
716  {
717  ret = VNET_API_ERROR_SYSCALL_ERROR_6;
718  goto error;
719  }
720  if (listen (msf->fd, 1) == -1)
721  {
722  ret = VNET_API_ERROR_SYSCALL_ERROR_7;
723  goto error;
724  }
725 
726  if (stat ((char *) msf->filename, &file_stat) == -1)
727  {
728  ret = VNET_API_ERROR_SYSCALL_ERROR_8;
729  goto error;
730  }
731 
732  msf->unix_file_index = ~0;
733  unix_file_t template = { 0 };
735  template.file_descriptor = msf->fd;
736  template.private_data = mif->socket_file_index;
737  memif_file_add (&msf->unix_file_index, &template);
738  }
739 
740  msf->ref_cnt++;
741 
742  if (args->is_master == 0)
743  mif->flags |= MEMIF_IF_FLAG_IS_SLAVE;
744 
745  hw = vnet_get_hw_interface (vnm, mif->hw_if_index);
748  memif_input_node.index);
749 
750  mhash_set (&msf->dev_instance_by_id, &mif->id, mif->dev_instance, 0);
751 
752  if (pool_elts (mm->interfaces) == 1)
753  {
756  }
757  goto done;
758 
759 error:
760  if (mif->hw_if_index != ~0)
761  {
762  if (mif->mode == MEMIF_INTERFACE_MODE_IP)
764  else
766  mif->hw_if_index = ~0;
767  }
768  memif_delete_if (vm, mif);
769  return ret;
770 
771 done:
772  vec_free (socket_filename);
773  return rv;
774 }
775 
776 
777 static clib_error_t *
779 {
780  memif_main_t *mm = &memif_main;
782 
783  memset (mm, 0, sizeof (memif_main_t));
784 
785  /* initialize binary API */
787 
789 
792 
793  return 0;
794 }
795 
797 
798 /* *INDENT-OFF* */
800  .version = VPP_BUILD_VER,
801  .description = "Packet Memory Interface (experimetal)",
802 };
803 /* *INDENT-ON* */
804 
805 /*
806  * fd.io coding-style-patch-verification: ON
807  *
808  * Local Variables:
809  * eval: (c-set-style "gnu")
810  * End:
811  */
#define DBG_UNIX_LOG(...)
memif_if_t * interfaces
Definition: private.h:189
vmrglw vmrglh hi
memif_ring_type_t
Definition: memif.h:47
#define vec_foreach_index(var, v)
Iterate over vector indices.
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
memif_ring_t * ring
Definition: private.h:100
memif_desc_t desc[0]
Definition: memif.h:174
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:537
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
unix_file_function_t * read_function
Definition: unix.h:62
#define hash_unset(h, key)
Definition: hash.h:260
u8 * secret
Definition: private.h:146
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:295
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
mhash_t socket_file_index_by_filename
Definition: private.h:193
memif_socket_file_t * socket_files
Definition: private.h:192
memif_log2_ring_size_t log2_ring_size
Definition: private.h:162
#define NULL
Definition: clib.h:55
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
Definition: mhash.c:353
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:192
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
static clib_error_t * memif_init(vlib_main_t *vm)
Definition: memif.c:778
clib_error_t * memif_msg_send_disconnect(memif_if_t *mif, clib_error_t *err)
Definition: socket.c:212
memif_interface_mode_t mode
Definition: private.h:216
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:397
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:447
u8 num_m2s_rings
Definition: private.h:164
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
struct memif_if_t::@330 cfg
#define MEMIF_RING_FLAG_MASK_INT
Definition: memif.h:169
#define MFD_ALLOW_SEALING
Definition: private.h:260
#define memif_file_del_by_index(a)
Definition: private.h:65
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
uword unix_file_index
Definition: private.h:72
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)
vnet_hw_interface_rx_mode
Definition: interface.h:51
#define MEMIF_DEFAULT_SOCKET_DIR
Definition: private.h:20
#define static_always_inline
Definition: clib.h:85
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
u8 * remote_name
Definition: private.h:157
#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:306
uword socket_file_index
Definition: private.h:142
uint32_t cookie
Definition: memif.h:167
clib_error_t * memif_init_regions_and_queues(memif_if_t *mif)
Definition: memif.c:263
static_always_inline void vnet_device_input_set_interrupt_pending(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.h:135
u16 buffer_size
Definition: private.h:165
memif_log2_ring_size_t log2_ring_size
Definition: private.h:217
#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:139
#define clib_error_return(e, args...)
Definition: error.h:99
static int memfd_create(const char *name, unsigned int flags)
Definition: private.h:245
memif_region_offset_t offset
Definition: private.h:103
unsigned long u64
Definition: types.h:89
#define memif_file_add(a, b)
Definition: private.h:60
void * shm
Definition: private.h:86
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:688
static u32 memif_eth_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
Definition: memif.c:45
mhash_t dev_instance_by_id
Definition: private.h:78
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:33
memif_region_index_t region
Definition: memif.h:150
u16 last_head
Definition: private.h:105
vlib_node_registration_t memif_input_node
(constructor) VLIB_REGISTER_NODE (memif_input_node)
Definition: node.c:512
u32 file_descriptor
Definition: unix.h:52
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:946
uword private_data
Definition: unix.h:59
int memif_delete_if(vlib_main_t *vm, memif_if_t *mif)
Definition: memif.c:472
uword dev_instance
Definition: private.h:136
clib_spinlock_t lockp
Definition: private.h:131
#define clib_error_return_unix(e, args...)
Definition: error.h:102
pid_t remote_pid
Definition: private.h:154
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:292
#define hash_free(h)
Definition: hash.h:286
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:374
memif_interface_id_t id
Definition: private.h:212
int memif_create_if(vlib_main_t *vm, memif_create_if_args_t *args)
Definition: memif.c:542
#define VNET_HW_INTERFACE_FLAG_SUPPORTS_INT_MODE
Definition: interface.h:423
VNET_HW_INTERFACE_CLASS(memif_ip_hw_if_class, static)
#define F_ADD_SEALS
Definition: private.h:261
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
Definition: mhash.h:117
#define F_SEAL_SHRINK
Definition: private.h:265
memif_queue_t * tx_queues
Definition: private.h:151
clib_error_t * memif_connect(memif_if_t *mif)
Definition: memif.c:172
uint32_t memif_interface_id_t
Definition: memif.h:64
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
u8 * local_disc_string
Definition: private.h:177
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
static clib_error_t * memif_int_fd_read_ready(unix_file_t *uf)
Definition: memif.c:147
#define clib_warning(format, args...)
Definition: error.h:59
#define DBG(...)
void memif_disconnect(memif_if_t *mif, clib_error_t *err)
Definition: memif.c:68
struct memif_if_t::@331 run
memif_region_t * regions
Definition: private.h:148
#define hash_create(elts, value_bytes)
Definition: hash.h:658
u32 ** rx_buffers
Definition: private.h:196
#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:122
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:52
static void mhash_free(mhash_t *h)
Definition: mhash.h:149
clib_error_t * memif_conn_fd_accept_ready(unix_file_t *uf)
Definition: socket.c:691
u32 flags
Definition: private.h:132
u64 size
Definition: vhost-user.h:75
int conn_fd
Definition: private.h:143
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:246
uword conn_unix_file_index
Definition: private.h:144
#define clib_error_report(e)
Definition: error.h:113
u32 hw_if_index
Definition: private.h:134
#define clib_fifo_free(f)
Definition: fifo.h:257
u64 int_count
Definition: private.h:111
void vnet_delete_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:897
u64 uword
Definition: types.h:112
memif_region_offset_t offset
Definition: memif.h:154
uword * dev_instance_by_fd
Definition: private.h:81
u8 num_s2m_rings
Definition: private.h:163
VLIB_PLUGIN_REGISTER()
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:249
#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:21
#define MEMIF_COOKIE
Definition: memif.h:25
uword int_unix_file_index
Definition: private.h:110
Definition: unix.h:49
a point 2 point interface
Definition: interface.h:292
#define clib_error_free(e)
Definition: error.h:86
u8 * remote_if_name
Definition: private.h:158
memif_interface_id_t id
Definition: private.h:133
memif_log2_ring_size_t log2_ring_size
Definition: private.h:101
int vnet_hw_interface_unassign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.c:171
static u32 random_u32(u32 *seed)
32-bit random number generator
Definition: random.h:69
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:144
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:464
u8 * remote_disc_string
Definition: private.h:178
#define vec_foreach(var, vec)
Vector iterator.
volatile uint16_t head
Definition: memif.h:170
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:545
memif_queue_t * rx_queues
Definition: private.h:150
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:236
uword * pending_file_indices
Definition: private.h:73
u32 flags
Definition: vhost-user.h:76
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
memif_msg_fifo_elt_t * msg_queue
Definition: private.h:145
memif_main_t memif_main
Definition: memif.c:42
memif_region_index_t region
Definition: private.h:102
u32 sw_if_index
Definition: private.h:135
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: devices.h:78
volatile uint16_t tail
Definition: memif.h:172
memif_interface_mode_t mode
Definition: private.h:137
static uword memif_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: memif.c:360
memif_region_size_t region_size
Definition: private.h:87
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:109