FD.io VPP  v20.01-48-g3e0dafb74
Vector Packet Processing
device.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2016 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 
22 #include <vlib/vlib.h>
23 #include <vlib/unix/unix.h>
24 #include <vnet/ethernet/ethernet.h>
25 #include <vnet/gso/gso.h>
26 #include <vnet/ip/ip4_packet.h>
27 #include <vnet/ip/ip6_packet.h>
28 #include <vnet/tcp/tcp_packet.h>
29 #include <vnet/udp/udp_packet.h>
31 
32 #define foreach_virtio_tx_func_error \
33 _(NO_FREE_SLOTS, "no free tx slots") \
34 _(TRUNC_PACKET, "packet > buffer size -- truncated in tx ring") \
35 _(PENDING_MSGS, "pending msgs in tx ring") \
36 _(NO_TX_QUEUES, "no tx queues") \
37 _(OUT_OF_ORDER, "out-of-order buffers in used ring")
38 
39 typedef enum
40 {
41 #define _(f,s) VIRTIO_TX_ERROR_##f,
43 #undef _
46 
47 static char *virtio_tx_func_error_strings[] = {
48 #define _(n,s) s,
50 #undef _
51 };
52 
53 static u8 *
54 format_virtio_device (u8 * s, va_list * args)
55 {
56  u32 dev_instance = va_arg (*args, u32);
57  int verbose = va_arg (*args, int);
58  u32 indent = format_get_indent (s);
59 
60  s = format (s, "VIRTIO interface");
61  if (verbose)
62  {
63  s = format (s, "\n%U instance %u", format_white_space, indent + 2,
64  dev_instance);
65  }
66  return s;
67 }
68 
69 static u8 *
70 format_virtio_tx_trace (u8 * s, va_list * args)
71 {
72  s = format (s, "Unimplemented...");
73  return s;
74 }
75 
77 virtio_memset_ring_u32 (u32 * ring, u32 start, u32 ring_size, u32 n_buffers)
78 {
79  ASSERT (n_buffers <= ring_size);
80 
81  if (PREDICT_TRUE (start + n_buffers <= ring_size))
82  {
83  clib_memset_u32 (ring + start, ~0, n_buffers);
84  }
85  else
86  {
87  clib_memset_u32 (ring + start, ~0, ring_size - start);
88  clib_memset_u32 (ring, ~0, n_buffers - (ring_size - start));
89  }
90 }
91 
94  uword node_index)
95 {
96  u16 used = vring->desc_in_use;
97  u16 sz = vring->size;
98  u16 mask = sz - 1;
99  u16 last = vring->last_used_idx;
100  u16 n_left = vring->used->idx - last;
101  u16 out_of_order_count = 0;
102 
103  if (n_left == 0)
104  return;
105 
106  while (n_left)
107  {
108  struct vring_used_elem *e = &vring->used->ring[last & mask];
109  u16 slot, n_buffers;
110  slot = n_buffers = e->id;
111 
112  while (e->id == (n_buffers & mask))
113  {
114  n_left--;
115  last++;
116  n_buffers++;
117  if (n_left == 0)
118  break;
119  e = &vring->used->ring[last & mask];
120  }
121  vlib_buffer_free_from_ring (vm, vring->buffers, slot,
122  sz, (n_buffers - slot));
123  virtio_memset_ring_u32 (vring->buffers, slot, sz, (n_buffers - slot));
124  used -= (n_buffers - slot);
125 
126  if (n_left > 0)
127  {
128  vlib_buffer_free (vm, &vring->buffers[e->id], 1);
129  vring->buffers[e->id] = ~0;
130  used--;
131  last++;
132  n_left--;
133  out_of_order_count++;
134  vring->flags |= VRING_TX_OUT_OF_ORDER;
135  }
136  }
137 
138  /*
139  * Some vhost-backends give buffers back in out-of-order fashion in used ring.
140  * It impacts the overall virtio-performance.
141  */
142  if (out_of_order_count)
143  vlib_error_count (vm, node_index, VIRTIO_TX_ERROR_OUT_OF_ORDER,
144  out_of_order_count);
145 
146  vring->desc_in_use = used;
147  vring->last_used_idx = last;
148 }
149 
152  struct virtio_net_hdr_v1 *hdr)
153 {
154  if (b->flags & VNET_BUFFER_F_IS_IP4)
155  {
156  ip4_header_t *ip4;
158  hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
159  hdr->csum_start = gho.l4_hdr_offset; // 0x22;
160  if (b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM)
161  hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum);
162  else if (b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM)
163  hdr->csum_offset = STRUCT_OFFSET_OF (udp_header_t, checksum);
164 
165  /*
166  * virtio devices do not support IP4 checksum offload. So driver takes care
167  * of it while doing tx.
168  */
169  ip4 =
171  if (b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM)
172  ip4->checksum = ip4_header_checksum (ip4);
173  }
174  else if (b->flags & VNET_BUFFER_F_IS_IP6)
175  {
177  hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
178  hdr->csum_start = gho.l4_hdr_offset; // 0x36;
179  if (b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM)
180  hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum);
181  else if (b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM)
182  hdr->csum_offset = STRUCT_OFFSET_OF (udp_header_t, checksum);
183  }
184 }
185 
188  virtio_vring_t * vring, u32 bi, u16 avail, u16 next,
189  u16 mask, int do_gso, int csum_offload)
190 {
191  u16 n_added = 0;
192  int hdr_sz = vif->virtio_net_hdr_sz;
193  struct vring_desc *d;
194  d = &vring->desc[next];
195  vlib_buffer_t *b = vlib_get_buffer (vm, bi);
196  struct virtio_net_hdr_v1 *hdr = vlib_buffer_get_current (b) - hdr_sz;
197 
198  clib_memset (hdr, 0, hdr_sz);
199 
200  if (do_gso && (b->flags & VNET_BUFFER_F_GSO))
201  {
202  if (b->flags & VNET_BUFFER_F_IS_IP4)
203  {
204  ip4_header_t *ip4;
206  hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
207  hdr->gso_size = vnet_buffer2 (b)->gso_size;
208  hdr->hdr_len = gho.l4_hdr_offset + gho.l4_hdr_sz;
209  hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
210  hdr->csum_start = gho.l4_hdr_offset; // 0x22;
211  hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum);
212  ip4 =
214  gho.l3_hdr_offset);
215  /*
216  * virtio devices do not support IP4 checksum offload. So driver takes care
217  * of it while doing tx.
218  */
219  if (b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM)
220  ip4->checksum = ip4_header_checksum (ip4);
221  }
222  else if (b->flags & VNET_BUFFER_F_IS_IP6)
223  {
225  hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
226  hdr->gso_size = vnet_buffer2 (b)->gso_size;
227  hdr->hdr_len = gho.l4_hdr_offset + gho.l4_hdr_sz;
228  hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
229  hdr->csum_start = gho.l4_hdr_offset; // 0x36;
230  hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum);
231  }
232  }
233  else if (csum_offload
234  && (b->flags & (VNET_BUFFER_F_OFFLOAD_TCP_CKSUM |
235  VNET_BUFFER_F_OFFLOAD_UDP_CKSUM)))
236  {
237  set_checksum_offsets (vm, vif, b, hdr);
238  }
239 
240  if (PREDICT_TRUE ((b->flags & VLIB_BUFFER_NEXT_PRESENT) == 0))
241  {
242  d->addr =
244  b) :
246  d->len = b->current_length + hdr_sz;
247  d->flags = 0;
248  }
249  else
250  {
251  /*
252  * We are using single vlib_buffer_t for indirect descriptor(s)
253  * chain. Single descriptor is 16 bytes and vlib_buffer_t
254  * has 2048 bytes space. So maximum long chain can have 128
255  * (=2048/16) indirect descriptors.
256  * It can easily support 65535 bytes of Jumbo frames with
257  * each data buffer size of 512 bytes minimum.
258  */
259  u32 indirect_buffer = 0;
260  if (PREDICT_FALSE (vlib_buffer_alloc (vm, &indirect_buffer, 1) == 0))
261  return n_added;
262 
263  vlib_buffer_t *indirect_desc = vlib_get_buffer (vm, indirect_buffer);
264  indirect_desc->current_data = 0;
265  indirect_desc->flags |= VLIB_BUFFER_NEXT_PRESENT;
266  indirect_desc->next_buffer = bi;
267  bi = indirect_buffer;
268 
269  struct vring_desc *id =
270  (struct vring_desc *) vlib_buffer_get_current (indirect_desc);
271  u32 count = 1;
272  if (vif->type == VIRTIO_IF_TYPE_PCI)
273  {
274  d->addr = vlib_physmem_get_pa (vm, id);
275  id->addr = vlib_buffer_get_current_pa (vm, b) - hdr_sz;
276 
277  /*
278  * If VIRTIO_F_ANY_LAYOUT is not negotiated, then virtio_net_hdr
279  * should be presented in separate descriptor and data will start
280  * from next descriptor.
281  */
282  if (PREDICT_TRUE
283  (vif->features & VIRTIO_FEATURE (VIRTIO_F_ANY_LAYOUT)))
284  id->len = b->current_length + hdr_sz;
285  else
286  {
287  id->len = hdr_sz;
288  id->flags = VRING_DESC_F_NEXT;
289  id->next = count;
290  count++;
291  id++;
292  id->addr = vlib_buffer_get_current_pa (vm, b);
293  id->len = b->current_length;
294  }
295  while (b->flags & VLIB_BUFFER_NEXT_PRESENT)
296  {
297  id->flags = VRING_DESC_F_NEXT;
298  id->next = count;
299  count++;
300  id++;
301  b = vlib_get_buffer (vm, b->next_buffer);
302  id->addr = vlib_buffer_get_current_pa (vm, b);
303  id->len = b->current_length;
304  }
305  }
306  else /* VIRTIO_IF_TYPE_TAP */
307  {
308  d->addr = pointer_to_uword (id);
309  /* first buffer in chain */
310  id->addr = pointer_to_uword (vlib_buffer_get_current (b)) - hdr_sz;
311  id->len = b->current_length + hdr_sz;
312 
313  while (b->flags & VLIB_BUFFER_NEXT_PRESENT)
314  {
315  id->flags = VRING_DESC_F_NEXT;
316  id->next = count;
317  count++;
318  id++;
319  b = vlib_get_buffer (vm, b->next_buffer);
320  id->addr = pointer_to_uword (vlib_buffer_get_current (b));
321  id->len = b->current_length;
322  }
323  }
324  id->flags = 0;
325  id->next = 0;
326  d->len = count * sizeof (struct vring_desc);
327  d->flags = VRING_DESC_F_INDIRECT;
328  }
329  vring->buffers[next] = bi;
330  vring->avail->ring[avail & mask] = next;
331  n_added++;
332  return n_added;
333 }
334 
337  u16 req, u16 next, u32 * first_free_desc_index,
338  u16 * free_desc_count)
339 {
340  u16 start = 0;
341  /* next is used as hint: from where to start looking */
342  for (u16 i = 0; i < size; i++, next++)
343  {
344  if (vring->buffers[next & mask] == ~0)
345  {
346  if (*first_free_desc_index == ~0)
347  {
348  *first_free_desc_index = (next & mask);
349  start = i;
350  (*free_desc_count)++;
351  req--;
352  if (req == 0)
353  break;
354  }
355  else
356  {
357  if (start + *free_desc_count == i)
358  {
359  (*free_desc_count)++;
360  req--;
361  if (req == 0)
362  break;
363  }
364  else
365  break;
366  }
367  }
368  }
369 }
370 
373  vlib_frame_t * frame, virtio_if_t * vif,
374  int do_gso, int csum_offload)
375 {
376  u16 n_left = frame->n_vectors;
377  virtio_vring_t *vring;
378  u16 qid = vm->thread_index % vif->num_txqs;
379  vring = vec_elt_at_index (vif->txq_vrings, qid);
380  u16 used, next, avail;
381  u16 sz = vring->size;
382  u16 mask = sz - 1;
383  u16 retry_count = 2;
384  u32 *buffers = vlib_frame_vector_args (frame);
385 
387 
388  if ((vring->used->flags & VIRTIO_RING_FLAG_MASK_INT) == 0 &&
389  (vring->last_kick_avail_idx != vring->avail->idx))
390  virtio_kick (vm, vring, vif);
391 
392 retry:
393  /* free consumed buffers */
394  virtio_free_used_device_desc (vm, vring, node->node_index);
395 
396  used = vring->desc_in_use;
397  next = vring->desc_next;
398  avail = vring->avail->idx;
399 
400  u16 free_desc_count = 0;
401 
403  {
404  u32 first_free_desc_index = ~0;
405 
406  virtio_find_free_desc (vring, sz, mask, n_left, next,
407  &first_free_desc_index, &free_desc_count);
408 
409  if (free_desc_count)
410  next = first_free_desc_index;
411  }
412  else
413  free_desc_count = sz - used;
414 
415  while (n_left && free_desc_count)
416  {
417  u16 n_added = 0;
418  n_added =
419  add_buffer_to_slot (vm, vif, vring, buffers[0], avail, next, mask,
420  do_gso, csum_offload);
421  if (!n_added)
422  break;
423  avail += n_added;
424  next = (next + n_added) & mask;
425  used += n_added;
426  buffers++;
427  n_left--;
428  free_desc_count--;
429  }
430 
431  if (n_left != frame->n_vectors)
432  {
434  vring->avail->idx = avail;
435  vring->desc_next = next;
436  vring->desc_in_use = used;
437  if ((vring->used->flags & VIRTIO_RING_FLAG_MASK_INT) == 0)
438  virtio_kick (vm, vring, vif);
439  }
440 
441  if (n_left)
442  {
443  if (retry_count--)
444  goto retry;
445 
446  vlib_error_count (vm, node->node_index, VIRTIO_TX_ERROR_NO_FREE_SLOTS,
447  n_left);
448  vlib_buffer_free (vm, buffers, n_left);
449  }
450 
452 
453  return frame->n_vectors - n_left;
454 }
455 
459 {
460  vnet_main_t *vnm = vnet_get_main ();
461  virtio_main_t *nm = &virtio_main;
462  vnet_interface_output_runtime_t *rund = (void *) node->runtime_data;
464  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, vif->hw_if_index);
465 
467  return virtio_interface_tx_inline (vm, node, frame, vif, 1 /* do_gso */ ,
468  1);
470  return virtio_interface_tx_inline (vm, node, frame, vif,
471  0 /* no do_gso */ , 1);
472  else
473  return virtio_interface_tx_inline (vm, node, frame, vif,
474  0 /* no do_gso */ , 0);
475 }
476 
477 static void
479  u32 node_index)
480 {
481  virtio_main_t *apm = &virtio_main;
482  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
484 
485  /* Shut off redirection */
486  if (node_index == ~0)
487  {
488  vif->per_interface_next_index = node_index;
489  return;
490  }
491 
494  node_index);
495 }
496 
497 static void
499 {
500  /* Nothing for now */
501 }
502 
503 static clib_error_t *
506 {
507  virtio_main_t *mm = &virtio_main;
508  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
510  virtio_vring_t *vring = vec_elt_at_index (vif->rxq_vrings, qid);
511 
512  if (vif->type == VIRTIO_IF_TYPE_PCI && !(vif->support_int_mode))
513  {
514  vring->avail->flags |= VIRTIO_RING_FLAG_MASK_INT;
515  return clib_error_return (0, "interrupt mode is not supported");
516  }
517 
519  vring->avail->flags |= VIRTIO_RING_FLAG_MASK_INT;
520  else
521  vring->avail->flags &= ~VIRTIO_RING_FLAG_MASK_INT;
522 
523  return 0;
524 }
525 
526 static clib_error_t *
528 {
529  virtio_main_t *mm = &virtio_main;
530  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
532 
534  {
535  vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP;
538  }
539  else
540  {
541  vif->flags &= ~VIRTIO_IF_FLAG_ADMIN_UP;
543  }
544  return 0;
545 }
546 
547 static clib_error_t *
549  u32 hw_if_index,
550  struct vnet_sw_interface_t *st, int is_add)
551 {
552  /* Nothing for now */
553  return 0;
554 }
555 
556 /* *INDENT-OFF* */
558  .name = "virtio",
559  .format_device_name = format_virtio_device_name,
560  .format_device = format_virtio_device,
561  .format_tx_trace = format_virtio_tx_trace,
562  .tx_function_n_errors = VIRTIO_TX_N_ERROR,
563  .tx_function_error_strings = virtio_tx_func_error_strings,
564  .rx_redirect_to_node = virtio_set_interface_next_node,
565  .clear_counters = virtio_clear_hw_interface_counters,
566  .admin_up_down_function = virtio_interface_admin_up_down,
567  .subif_add_del_function = virtio_subif_add_del_function,
568  .rx_mode_change_function = virtio_interface_rx_mode_change,
569 };
570 /* *INDENT-ON* */
571 
572 /*
573  * fd.io coding-style-patch-verification: ON
574  *
575  * Local Variables:
576  * eval: (c-set-style "gnu")
577  * End:
578  */
u32 per_interface_next_index
Definition: virtio.h:151
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:124
u8 count
Definition: dhcp.api:208
struct vring_used * used
Definition: virtio.h:105
static uword vlib_buffer_get_current_pa(vlib_main_t *vm, vlib_buffer_t *b)
Definition: buffer_funcs.h:427
vlib_node_registration_t virtio_input_node
(constructor) VLIB_REGISTER_NODE (virtio_input_node)
Definition: node.c:414
virtio_if_t * interfaces
Definition: virtio.h:188
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:890
#define foreach_virtio_tx_func_error
Definition: device.c:32
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#define vnet_buffer2(b)
Definition: buffer.h:467
#define PREDICT_TRUE(x)
Definition: clib.h:112
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:110
#define CLIB_MEMORY_STORE_BARRIER()
Definition: clib.h:118
static void vlib_error_count(vlib_main_t *vm, uword node_index, uword counter, uword increment)
Definition: error_funcs.h:57
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
Definition: lock.h:110
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
u32 thread_index
Definition: main.h:218
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:113
static heap_elt_t * last(heap_header_t *h)
Definition: heap.c:53
int i
static u32 format_get_indent(u8 *s)
Definition: format.h:72
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:65
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
struct _tcp_header tcp_header_t
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1092
static_always_inline u16 add_buffer_to_slot(vlib_main_t *vm, virtio_if_t *vif, virtio_vring_t *vring, u32 bi, u16 avail, u16 next, u16 mask, int do_gso, int csum_offload)
Definition: device.c:187
unsigned char u8
Definition: types.h:56
static char * virtio_tx_func_error_strings[]
Definition: device.c:47
virtio_tx_func_error_t
Definition: device.c:39
vnet_hw_interface_rx_mode
Definition: interface.h:53
struct vring_avail * avail
Definition: virtio.h:106
u64 features
Definition: virtio.h:158
#define static_always_inline
Definition: clib.h:99
u32 hw_if_index
Definition: virtio.h:141
i16 l3_hdr_offset
Definition: gso.h:28
VNET_DEVICE_CLASS_TX_FN() virtio_device_class(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: device.c:456
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
u8 support_int_mode
Definition: virtio.h:162
vnet_hw_interface_flags_t flags
Definition: interface.h:523
#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:107
static void virtio_clear_hw_interface_counters(u32 instance)
Definition: device.c:498
#define clib_error_return(e, args...)
Definition: error.h:99
#define VNET_DEVICE_CLASS_TX_FN(devclass)
Definition: interface.h:305
unsigned int u32
Definition: types.h:88
vl_api_gre_tunnel_mode_t mode
Definition: gre.api:55
static clib_error_t * virtio_interface_rx_mode_change(vnet_main_t *vnm, u32 hw_if_index, u32 qid, vnet_hw_interface_rx_mode mode)
Definition: device.c:504
u16 num_txqs
Definition: virtio.h:165
static void vlib_buffer_free_from_ring(vlib_main_t *vm, u32 *ring, u32 start, u32 ring_size, u32 n_buffers)
Free buffers from ring.
Definition: buffer_funcs.h:937
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
static_always_inline void virtio_memset_ring_u32(u32 *ring, u32 start, u32 ring_size, u32 n_buffers)
Definition: device.c:77
unsigned short u16
Definition: types.h:57
u64 size
Definition: vhost_user.h:140
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
#define PREDICT_FALSE(x)
Definition: clib.h:111
u32 node_index
Node index.
Definition: node.h:496
vlib_main_t * vm
Definition: in2out_ed.c:1810
static u8 * format_virtio_device(u8 *s, va_list *args)
Definition: device.c:54
u16 desc_next
Definition: virtio.h:109
u16 virtio_net_hdr_sz
Definition: virtio.h:144
static void virtio_set_interface_next_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: device.c:478
u8 slot
Definition: pci_types.api:22
virtio_vring_t * rxq_vrings
Definition: virtio.h:156
format_function_t format_virtio_device_name
Definition: virtio.h:210
u16 last_used_idx
Definition: virtio.h:119
static_always_inline uword virtio_interface_tx_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, virtio_if_t *vif, int do_gso, int csum_offload)
Definition: device.c:372
u32 flags
Definition: vhost_user.h:141
u16 n_vectors
Definition: node.h:397
static u8 * format_virtio_tx_trace(u8 *s, va_list *args)
Definition: device.c:70
#define VIRTIO_RING_FLAG_MASK_INT
Definition: virtio.h:99
static clib_error_t * virtio_subif_add_del_function(vnet_main_t *vnm, u32 hw_if_index, struct vnet_sw_interface_t *st, int is_add)
Definition: device.c:548
static_always_inline void set_checksum_offsets(vlib_main_t *vm, virtio_if_t *vif, vlib_buffer_t *b, struct virtio_net_hdr_v1 *hdr)
Definition: device.c:151
i16 l4_hdr_offset
Definition: gso.h:29
static clib_error_t * virtio_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: device.c:527
u32 flags
Definition: virtio.h:138
u16 last_kick_avail_idx
Definition: virtio.h:120
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1810
virtio_if_type_t type
Definition: virtio.h:145
#define ASSERT(truth)
#define VIRTIO_FEATURE(X)
Definition: virtio.h:76
static_always_inline void virtio_find_free_desc(virtio_vring_t *vring, u16 size, u16 mask, u16 req, u16 next, u32 *first_free_desc_index, u16 *free_desc_count)
Definition: device.c:336
static uword pointer_to_uword(const void *p)
Definition: types.h:131
virtio_main_t virtio_main
Definition: virtio.c:37
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
#define VRING_TX_OUT_OF_ORDER
Definition: virtio.h:115
static u64 vlib_physmem_get_pa(vlib_main_t *vm, void *mem)
u32 next_buffer
Next buffer for this linked-list of buffers.
Definition: buffer.h:140
u32 instance
Definition: gre.api:57
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
Definition: interface.c:492
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
static_always_inline void virtio_free_used_device_desc(vlib_main_t *vm, virtio_vring_t *vring, uword node_index)
Definition: device.c:93
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:244
u32 * buffers
Definition: virtio.h:118
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1811
struct vring_desc * desc
Definition: virtio.h:104
u32 ip4
Definition: one.api:440
static u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: buffer_funcs.h:630
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:95
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:247
u16 desc_in_use
Definition: virtio.h:108
static_always_inline gso_header_offset_t vnet_gso_header_offset_parser(vlib_buffer_t *b0, int is_ip6)
Definition: gso.h:48
virtio_vring_t * txq_vrings
Definition: virtio.h:157
static_always_inline void virtio_kick(vlib_main_t *vm, virtio_vring_t *vring, virtio_if_t *vif)
Definition: virtio.h:214
VNET_DEVICE_CLASS(avf_device_class,)
static_always_inline void clib_memset_u32(void *p, u32 val, uword count)
Definition: string.h:332