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