FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
virtio.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 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <net/if.h>
22 #include <linux/if_tun.h>
23 #include <sys/ioctl.h>
24 #include <sys/eventfd.h>
25 
26 #include <vlib/vlib.h>
27 #include <vlib/pci/pci.h>
28 #include <vlib/unix/unix.h>
29 #include <vnet/ethernet/ethernet.h>
30 #include <vnet/ip/ip4_packet.h>
31 #include <vnet/ip/ip6_packet.h>
34 
36 
37 #define _IOCTL(fd,a,...) \
38  if (ioctl (fd, a, __VA_ARGS__) < 0) \
39  { \
40  err = clib_error_return_unix (0, "ioctl(" #a ")"); \
41  goto error; \
42  }
43 
44 static clib_error_t *
46 {
48  vnet_main_t *vnm = vnet_get_main ();
49  u16 qid = uf->private_data & 0xFFFF;
50  virtio_if_t *vif =
51  vec_elt_at_index (nm->interfaces, uf->private_data >> 16);
52  u64 b;
53 
54  CLIB_UNUSED (ssize_t size) = read (uf->file_descriptor, &b, sizeof (b));
55  if ((qid & 1) == 0)
57  RX_QUEUE_ACCESS (qid));
58 
59  return 0;
60 }
61 
62 
65 {
66  virtio_vring_t *vring;
67  clib_file_t t = { 0 };
68  int i;
69 
70  if (!is_pow2 (sz))
71  return clib_error_return (0, "ring size must be power of 2");
72 
73  if (sz > 32768)
74  return clib_error_return (0, "ring size must be 32768 or lower");
75 
76  if (sz == 0)
77  sz = 256;
78 
79  if (idx % 2)
80  {
84  vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS (idx));
85  if (thm->n_vlib_mains > vif->num_txqs)
86  clib_spinlock_init (&vring->lockp);
87  }
88  else
89  {
92  vring = vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS (idx));
93  }
94  i = sizeof (vring_desc_t) * sz;
97  clib_memset (vring->desc, 0, i);
98 
99  i = sizeof (vring_avail_t) + sz * sizeof (vring->avail->ring[0]);
102  clib_memset (vring->avail, 0, i);
103  // tell kernel that we don't need interrupt
105 
106  i = sizeof (vring_used_t) + sz * sizeof (vring_used_elem_t);
109  clib_memset (vring->used, 0, i);
110 
111  vring->queue_id = idx;
112  ASSERT (vring->buffers == 0);
114 
115  if (idx & 1)
116  {
117  clib_memset_u32 (vring->buffers, ~0, sz);
118  }
119 
120  vring->size = sz;
121  vring->call_fd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
122  vring->kick_fd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
123  virtio_log_debug (vif, "vring %u size %u call_fd %d kick_fd %d", idx,
124  vring->size, vring->call_fd, vring->kick_fd);
125 
127  t.file_descriptor = vring->call_fd;
128  t.private_data = vif->dev_instance << 16 | idx;
129  t.description = format (0, "%U vring %u", format_virtio_device_name,
130  vif->dev_instance, idx);
131  vring->call_file_index = clib_file_add (&file_main, &t);
132 
133  return 0;
134 }
135 
136 inline void
138 {
139  u16 used = vring->desc_in_use;
140  u16 last = vring->last_used_idx;
141  u16 mask = vring->size - 1;
142 
143  while (used)
144  {
145  vlib_buffer_free (vm, &vring->buffers[last & mask], 1);
146  last++;
147  used--;
148  }
149 }
150 
151 clib_error_t *
153 {
154  virtio_vring_t *vring =
156 
158  close (vring->kick_fd);
159  close (vring->call_fd);
160  if (vring->used)
161  {
162  virtio_free_rx_buffers (vm, vring);
163  clib_mem_free (vring->used);
164  }
165  if (vring->desc)
166  clib_mem_free (vring->desc);
167  if (vring->avail)
168  clib_mem_free (vring->avail);
169  vec_free (vring->buffers);
170  return 0;
171 }
172 
173 inline void
175 {
176  u16 used = vring->desc_in_use;
177  u16 sz = vring->size;
178  u16 mask = sz - 1;
179  u16 last = vring->last_used_idx;
180  u16 n_left = vring->used->idx - last;
181 
182  if (n_left == 0)
183  return;
184 
185  while (n_left)
186  {
187  vring_used_elem_t *e = &vring->used->ring[last & mask];
188  u16 slot = e->id;
189 
190  vlib_buffer_free (vm, &vring->buffers[slot], 1);
191  used--;
192  last++;
193  n_left--;
194  }
195  vring->desc_in_use = used;
196  vring->last_used_idx = last;
197 }
198 
199 clib_error_t *
201 {
202  virtio_vring_t *vring =
204 
206  close (vring->kick_fd);
207  close (vring->call_fd);
208  if (vring->used)
209  {
210  virtio_free_used_desc (vm, vring);
211  clib_mem_free (vring->used);
212  }
213  if (vring->desc)
214  clib_mem_free (vring->desc);
215  if (vring->avail)
216  clib_mem_free (vring->avail);
217  vec_free (vring->buffers);
219  clib_spinlock_free (&vring->lockp);
220  return 0;
221 }
222 
223 void
225 {
226  vnet_main_t *vnm = vnet_get_main ();
228  virtio_vring_t *vring;
229  vif->packet_coalesce = 1;
230  vec_foreach (vring, vif->txq_vrings)
231  {
233  vif->type & (VIRTIO_IF_TYPE_TAP |
234  VIRTIO_IF_TYPE_PCI), hw->tx_node_index);
235  }
236 }
237 
238 void
240 {
241  vnet_main_t *vnm = vnet_get_main ();
242  u32 thread_index;
243  virtio_vring_t *vring =
245  thread_index =
247  RX_QUEUE_ACCESS (idx));
248  vring->buffer_pool_index =
250  vlib_mains
251  [thread_index]->numa_node);
252 }
253 
254 inline void
256 {
257  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF) ||
258  vif->features & VIRTIO_FEATURE (VIRTIO_F_VERSION_1))
259  vif->virtio_net_hdr_sz = sizeof (virtio_net_hdr_v1_t);
260  else
261  vif->virtio_net_hdr_sz = sizeof (virtio_net_hdr_t);
262 }
263 
264 inline void
265 virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type)
266 {
267  u32 i, j, hw_if_index;
268  virtio_if_t *vif;
269  vnet_main_t *vnm = &vnet_main;
270  virtio_main_t *mm = &virtio_main;
271  virtio_vring_t *vring;
272  struct feat_struct
273  {
274  u8 bit;
275  char *str;
276  };
277  struct feat_struct *feat_entry;
278 
279  static struct feat_struct feat_array[] = {
280 #define _(s,b) { .str = #s, .bit = b, },
282 #undef _
283  {.str = NULL}
284  };
285 
286  struct feat_struct *flag_entry;
287  static struct feat_struct flags_array[] = {
288 #define _(b,e,s) { .bit = b, .str = s, },
290 #undef _
291  {.str = NULL}
292  };
293 
294  if (!hw_if_indices)
295  return;
296 
297  for (hw_if_index = 0; hw_if_index < vec_len (hw_if_indices); hw_if_index++)
298  {
300  vnet_get_hw_interface (vnm, hw_if_indices[hw_if_index]);
301  vif = pool_elt_at_index (mm->interfaces, hi->dev_instance);
302  if (vif->type != type)
303  continue;
304  vlib_cli_output (vm, "Interface: %U (ifindex %d)",
306  hw_if_indices[hw_if_index], vif->hw_if_index);
307  if (type == VIRTIO_IF_TYPE_PCI)
308  {
309  vlib_cli_output (vm, " PCI Address: %U", format_vlib_pci_addr,
310  &vif->pci_addr);
311  }
312  if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN))
313  {
314  u8 *str = 0;
315  if (vif->host_if_name)
316  vlib_cli_output (vm, " name \"%s\"", vif->host_if_name);
317  if (vif->net_ns)
318  vlib_cli_output (vm, " host-ns \"%s\"", vif->net_ns);
319  if (vif->host_mtu_size)
320  vlib_cli_output (vm, " host-mtu-size \"%d\"",
321  vif->host_mtu_size);
322  if (type == VIRTIO_IF_TYPE_TAP)
323  vlib_cli_output (vm, " host-mac-addr: %U",
325 
326  vec_foreach_index (i, vif->vhost_fds)
327  str = format (str, " %d", vif->vhost_fds[i]);
328  vlib_cli_output (vm, " vhost-fds%v", str);
329  vec_free (str);
330  vec_foreach_index (i, vif->tap_fds)
331  str = format (str, " %d", vif->tap_fds[i]);
332  vlib_cli_output (vm, " tap-fds%v", str);
333  vec_free (str);
334  }
335  vlib_cli_output (vm, " gso-enabled %d", vif->gso_enabled);
336  vlib_cli_output (vm, " csum-enabled %d", vif->csum_offload_enabled);
337  vlib_cli_output (vm, " packet-coalesce %d", vif->packet_coalesce);
338  if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_PCI))
339  vlib_cli_output (vm, " Mac Address: %U", format_ethernet_address,
340  vif->mac_addr);
341  vlib_cli_output (vm, " Device instance: %u", vif->dev_instance);
342  vlib_cli_output (vm, " flags 0x%x", vif->flags);
343  flag_entry = (struct feat_struct *) &flags_array;
344  while (flag_entry->str)
345  {
346  if (vif->flags & (1ULL << flag_entry->bit))
347  vlib_cli_output (vm, " %s (%d)", flag_entry->str,
348  flag_entry->bit);
349  flag_entry++;
350  }
351  if (type == VIRTIO_IF_TYPE_PCI)
352  {
353  device_status (vm, vif);
354  }
355  vlib_cli_output (vm, " features 0x%lx", vif->features);
356  feat_entry = (struct feat_struct *) &feat_array;
357  while (feat_entry->str)
358  {
359  if (vif->features & (1ULL << feat_entry->bit))
360  vlib_cli_output (vm, " %s (%d)", feat_entry->str,
361  feat_entry->bit);
362  feat_entry++;
363  }
364  vlib_cli_output (vm, " remote-features 0x%lx", vif->remote_features);
365  feat_entry = (struct feat_struct *) &feat_array;
366  while (feat_entry->str)
367  {
368  if (vif->remote_features & (1ULL << feat_entry->bit))
369  vlib_cli_output (vm, " %s (%d)", feat_entry->str,
370  feat_entry->bit);
371  feat_entry++;
372  }
373  vlib_cli_output (vm, " Number of RX Virtqueue %u", vif->num_rxqs);
374  vlib_cli_output (vm, " Number of TX Virtqueue %u", vif->num_txqs);
375  if (vif->cxq_vring != NULL
376  && vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ))
377  vlib_cli_output (vm, " Number of CTRL Virtqueue 1");
378  vec_foreach_index (i, vif->rxq_vrings)
379  {
380  vring = vec_elt_at_index (vif->rxq_vrings, i);
381  vlib_cli_output (vm, " Virtqueue (RX) %d", vring->queue_id);
382  vlib_cli_output (vm,
383  " qsz %d, last_used_idx %d, desc_next %d, desc_in_use %d",
384  vring->size, vring->last_used_idx, vring->desc_next,
385  vring->desc_in_use);
386  vlib_cli_output (vm,
387  " avail.flags 0x%x avail.idx %d used.flags 0x%x used.idx %d",
388  vring->avail->flags, vring->avail->idx,
389  vring->used->flags, vring->used->idx);
390  if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN))
391  {
392  vlib_cli_output (vm, " kickfd %d, callfd %d", vring->kick_fd,
393  vring->call_fd);
394  }
395  if (show_descr)
396  {
397  vlib_cli_output (vm, "\n descriptor table:\n");
398  vlib_cli_output (vm,
399  " id addr len flags next user_addr\n");
400  vlib_cli_output (vm,
401  " ===== ================== ===== ====== ===== ==================\n");
402  for (j = 0; j < vring->size; j++)
403  {
404  vring_desc_t *desc = &vring->desc[j];
405  vlib_cli_output (vm,
406  " %-5d 0x%016lx %-5d 0x%04x %-5d 0x%016lx\n",
407  j, desc->addr,
408  desc->len,
409  desc->flags, desc->next, desc->addr);
410  }
411  }
412  }
413  vec_foreach_index (i, vif->txq_vrings)
414  {
415  vring = vec_elt_at_index (vif->txq_vrings, i);
416  vlib_cli_output (vm, " Virtqueue (TX) %d", vring->queue_id);
417  vlib_cli_output (vm,
418  " qsz %d, last_used_idx %d, desc_next %d, desc_in_use %d",
419  vring->size, vring->last_used_idx, vring->desc_next,
420  vring->desc_in_use);
421  vlib_cli_output (vm,
422  " avail.flags 0x%x avail.idx %d used.flags 0x%x used.idx %d",
423  vring->avail->flags, vring->avail->idx,
424  vring->used->flags, vring->used->idx);
425  if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN))
426  {
427  vlib_cli_output (vm, " kickfd %d, callfd %d", vring->kick_fd,
428  vring->call_fd);
429  }
430  if (vring->flow_table)
431  {
433  vring->flow_table);
434  }
435  if (show_descr)
436  {
437  vlib_cli_output (vm, "\n descriptor table:\n");
438  vlib_cli_output (vm,
439  " id addr len flags next user_addr\n");
440  vlib_cli_output (vm,
441  " ===== ================== ===== ====== ===== ==================\n");
442  for (j = 0; j < vring->size; j++)
443  {
444  vring_desc_t *desc = &vring->desc[j];
445  vlib_cli_output (vm,
446  " %-5d 0x%016lx %-5d 0x%04x %-5d 0x%016lx\n",
447  j, desc->addr,
448  desc->len,
449  desc->flags, desc->next, desc->addr);
450  }
451  }
452  }
453  if (vif->cxq_vring != NULL
454  && vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ))
455  {
456  vring = vif->cxq_vring;
457  vlib_cli_output (vm, " Virtqueue (CTRL) %d", vring->queue_id);
458  vlib_cli_output (vm,
459  " qsz %d, last_used_idx %d, desc_next %d, desc_in_use %d",
460  vring->size, vring->last_used_idx,
461  vring->desc_next, vring->desc_in_use);
462  vlib_cli_output (vm,
463  " avail.flags 0x%x avail.idx %d used.flags 0x%x used.idx %d",
464  vring->avail->flags, vring->avail->idx,
465  vring->used->flags, vring->used->idx);
466  if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN))
467  {
468  vlib_cli_output (vm, " kickfd %d, callfd %d", vring->kick_fd,
469  vring->call_fd);
470  }
471  if (show_descr)
472  {
473  vlib_cli_output (vm, "\n descriptor table:\n");
474  vlib_cli_output (vm,
475  " id addr len flags next user_addr\n");
476  vlib_cli_output (vm,
477  " ===== ================== ===== ====== ===== ==================\n");
478  for (j = 0; j < vring->size; j++)
479  {
480  vring_desc_t *desc = &vring->desc[j];
481  vlib_cli_output (vm,
482  " %-5d 0x%016lx %-5d 0x%04x %-5d 0x%016lx\n",
483  j, desc->addr,
484  desc->len,
485  desc->flags, desc->next, desc->addr);
486  }
487  }
488  }
489 
490  }
491 
492 }
493 
494 static clib_error_t *
496 {
497  virtio_main_t *vim = &virtio_main;
498  clib_error_t *error = 0;
499 
500  vim->log_default = vlib_log_register_class ("virtio", 0);
501  vlib_log_debug (vim->log_default, "initialized");
502 
503  return error;
504 }
505 
507 
508 /*
509  * fd.io coding-style-patch-verification: ON
510  *
511  * Local Variables:
512  * eval: (c-set-style "gnu")
513  * End:
514  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:209
gro_flow_table_t * flow_table
Definition: virtio.h:86
#define vec_foreach_index(var, v)
Iterate over vector indices.
format_function_t format_vnet_hw_if_index_name
void virtio_set_net_hdr_size(virtio_if_t *vif)
Definition: virtio.c:255
virtio_if_t * interfaces
Definition: virtio.h:192
#define CLIB_UNUSED(x)
Definition: clib.h:87
void virtio_show(vlib_main_t *vm, u32 *hw_if_indices, u8 show_descr, u32 type)
Definition: virtio.c:265
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
Definition: buffer_funcs.h:937
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
static_always_inline u8 * gro_flow_table_format(u8 *s, va_list *args)
Definition: gro.h:255
unsigned long u64
Definition: types.h:89
int gso_enabled
Definition: virtio.h:114
u32 host_mtu_size
Definition: virtio.h:159
u32 dev_instance
Definition: virtio.h:133
vring_used_elem_t ring[0]
Definition: virtio_std.h:113
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
int kick_fd
Definition: virtio.h:72
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
u32 file_descriptor
Definition: file.h:54
static heap_elt_t * last(heap_header_t *h)
Definition: heap.c:53
void virtio_vring_set_numa_node(vlib_main_t *vm, virtio_if_t *vif, u32 idx)
Definition: virtio.c:239
vlib_main_t * vm
Definition: in2out_ed.c:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:520
u16 mask
Definition: flow_types.api:52
int call_fd
Definition: virtio.h:73
vlib_main_t ** vlib_mains
Definition: buffer.c:332
unsigned char u8
Definition: types.h:56
clib_error_t * virtio_vring_free_tx(vlib_main_t *vm, virtio_if_t *vif, u32 idx)
Definition: virtio.c:200
#define VIRTIO_FEATURE(X)
Definition: virtio_std.h:69
vring_desc_t * desc
Definition: virtio.h:63
clib_file_function_t * read_function
Definition: file.h:67
static void clib_spinlock_free(clib_spinlock_t *p)
Definition: lock.h:70
#define VRING_AVAIL_F_NO_INTERRUPT
Definition: virtio_std.h:85
u64 features
Definition: virtio.h:107
u32 hw_if_index
Definition: virtio.h:128
u8 * format_ethernet_address(u8 *s, va_list *args)
Definition: format.c:44
static clib_error_t * virtio_init(vlib_main_t *vm)
Definition: virtio.c:495
#define TX_QUEUE_ACCESS(X)
Definition: virtio.h:38
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
void device_status(vlib_main_t *vm, virtio_if_t *vif)
Definition: pci.c:170
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
void virtio_free_rx_buffers(vlib_main_t *vm, virtio_vring_t *vring)
Definition: virtio.c:137
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
clib_spinlock_t lockp
Definition: virtio.h:62
#define clib_error_return(e, args...)
Definition: error.h:99
clib_file_main_t file_main
Definition: main.c:63
unsigned int u32
Definition: types.h:88
#define vlib_log_debug(...)
Definition: log.h:109
u16 queue_id
Definition: virtio.h:79
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:63
u16 num_txqs
Definition: virtio.h:111
vl_api_fib_path_type_t type
Definition: fib_types.api:123
u8 * description
Definition: file.h:70
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
int * vhost_fds
Definition: virtio.h:153
static_always_inline uword vnet_get_device_input_thread_index(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.h:127
vring_avail_t * avail
Definition: virtio.h:65
unsigned short u16
Definition: types.h:57
u32 size
Definition: vhost_user.h:106
pci_addr_t pci_addr
Definition: virtio.h:170
vnet_main_t vnet_main
Definition: misc.c:43
u8 buffer_pool_index
Definition: virtio.h:77
#define virtio_log_debug(vif, f,...)
Definition: virtio.h:244
int packet_coalesce
Definition: virtio.h:132
vring_used_t * used
Definition: virtio.h:64
u16 desc_next
Definition: virtio.h:67
u16 virtio_net_hdr_sz
Definition: virtio.h:125
u8 slot
Definition: pci_types.api:22
u16 num_rxqs
Definition: virtio.h:110
virtio_vring_t * rxq_vrings
Definition: virtio.h:112
format_function_t format_virtio_device_name
Definition: virtio.h:219
u16 last_used_idx
Definition: virtio.h:83
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
static_always_inline void gro_flow_table_free(gro_flow_table_t *flow_table)
Definition: gro.h:171
static_always_inline u32 gro_flow_table_init(gro_flow_table_t **flow_table, u8 is_l2, u32 node_index)
Definition: gro.h:120
u32 call_file_index
Definition: virtio.h:85
u8 * net_ns
Definition: virtio.h:155
u8 mac_addr[6]
Definition: virtio.h:146
u32 flags
Definition: virtio.h:108
vlib_log_class_t log_default
Definition: virtio.h:190
static uword round_pow2(uword x, uword pow2)
Definition: clib.h:264
virtio_if_type_t type
Definition: virtio.h:126
void virtio_free_used_desc(vlib_main_t *vm, virtio_vring_t *vring)
Definition: virtio.c:174
#define ASSERT(truth)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
u64 remote_features
Definition: virtio.h:135
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
Definition: file.h:96
static void clib_file_del_by_index(clib_file_main_t *um, uword index)
Definition: file.h:119
clib_error_t * virtio_vring_init(vlib_main_t *vm, virtio_if_t *vif, u16 idx, u16 sz)
Definition: virtio.c:64
u8 host_mac_addr[6]
Definition: virtio.h:157
static void clib_mem_free(void *p)
Definition: mem.h:215
void virtio_set_packet_coalesce(virtio_if_t *vif)
Definition: virtio.c:224
virtio_main_t virtio_main
Definition: virtio.c:35
vl_api_ip4_address_t hi
Definition: arp.api:37
static uword is_pow2(uword x)
Definition: clib.h:252
u16 ring[0]
Definition: virtio_std.h:99
#define RX_QUEUE_ACCESS(X)
Definition: virtio.h:39
int csum_offload_enabled
Definition: virtio.h:115
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 * buffers
Definition: virtio.h:82
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:165
virtio_vring_t * cxq_vring
Definition: virtio.h:169
clib_error_t * virtio_vring_free_rx(vlib_main_t *vm, virtio_if_t *vif, u32 idx)
Definition: virtio.c:152
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
#define vec_foreach(var, vec)
Vector iterator.
uword private_data
Definition: file.h:64
Definition: file.h:51
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
static u8 vlib_buffer_pool_get_default_for_numa(vlib_main_t *vm, u32 numa_node)
Definition: buffer_funcs.h:199
int * tap_fds
Definition: virtio.h:118
format_function_t format_vlib_pci_addr
Definition: pci.h:324
u16 desc_in_use
Definition: virtio.h:66
virtio_vring_t * txq_vrings
Definition: virtio.h:113
static clib_error_t * call_read_ready(clib_file_t *uf)
Definition: virtio.c:45
u8 * host_if_name
Definition: virtio.h:154
static_always_inline void clib_memset_u32(void *p, u32 val, uword count)
Definition: string.h:332