FD.io VPP  v19.08-27-gf4dcae4
Vector Packet Processing
tap.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 #define _GNU_SOURCE
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <net/if.h>
23 #include <linux/if_tun.h>
24 #include <sys/ioctl.h>
25 #include <linux/virtio_net.h>
26 #include <linux/vhost.h>
27 #include <sys/eventfd.h>
28 #include <sched.h>
29 
30 #include <linux/netlink.h>
31 #include <linux/rtnetlink.h>
32 
33 #include <vlib/vlib.h>
34 #include <vlib/unix/unix.h>
35 #include <vnet/ethernet/ethernet.h>
36 #include <vnet/ip/ip4_packet.h>
37 #include <vnet/ip/ip6_packet.h>
38 #include <vnet/devices/netlink.h>
40 #include <vnet/devices/tap/tap.h>
41 
43 
44 #define _IOCTL(fd,a,...) \
45  if (ioctl (fd, a, __VA_ARGS__) < 0) \
46  { \
47  err = clib_error_return_unix (0, "ioctl(" #a ")"); \
48  goto error; \
49  }
50 
51 static u32
53  u32 flags)
54 {
55  /* nothing for now */
56  //TODO On MTU change call vnet_netlink_set_if_mtu
57  return 0;
58 }
59 
60 static int
61 open_netns_fd (char *netns)
62 {
63  u8 *s = 0;
64  int fd;
65 
66  if (strncmp (netns, "pid:", 4) == 0)
67  s = format (0, "/proc/%u/ns/net%c", atoi (netns + 4), 0);
68  else if (netns[0] == '/')
69  s = format (0, "%s%c", netns, 0);
70  else
71  s = format (0, "/var/run/netns/%s%c", netns, 0);
72 
73  fd = open ((char *) s, O_RDONLY);
74  vec_free (s);
75  return fd;
76 }
77 
78 #define TAP_MAX_INSTANCE 1024
79 
80 void
82 {
83  vnet_main_t *vnm = vnet_get_main ();
84  virtio_main_t *vim = &virtio_main;
85  tap_main_t *tm = &tap_main;
88  int i;
89  int old_netns_fd = -1;
90  struct ifreq ifr;
91  size_t hdrsz;
92  struct vhost_memory *vhost_mem = 0;
93  virtio_if_t *vif = 0;
94  clib_error_t *err = 0;
95  int fd = -1;
96  char *host_if_name = 0;
97 
98  if (args->id != ~0)
99  {
100  if (clib_bitmap_get (tm->tap_ids, args->id))
101  {
102  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
103  args->error = clib_error_return (0, "interface already exists");
104  return;
105  }
106  }
107  else
108  {
109  args->id = clib_bitmap_first_clear (tm->tap_ids);
110  }
111 
112  if (args->id > TAP_MAX_INSTANCE)
113  {
114  args->rv = VNET_API_ERROR_UNSPECIFIED;
115  args->error = clib_error_return (0, "cannot find free interface id");
116  return;
117  }
118 
119  clib_memset (&ifr, 0, sizeof (ifr));
120  pool_get (vim->interfaces, vif);
121  vif->dev_instance = vif - vim->interfaces;
122  vif->tap_fd = -1;
123  vif->id = args->id;
124 
125  if ((vif->fd = open ("/dev/vhost-net", O_RDWR | O_NONBLOCK)) < 0)
126  {
127  args->rv = VNET_API_ERROR_SYSCALL_ERROR_1;
128  args->error = clib_error_return_unix (0, "open '/dev/vhost-net'");
129  goto error;
130  }
131 
132  _IOCTL (vif->fd, VHOST_GET_FEATURES, &vif->remote_features);
133 
134  if ((vif->remote_features & VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF)) == 0)
135  {
136  args->rv = VNET_API_ERROR_UNSUPPORTED;
137  args->error = clib_error_return (0, "vhost-net backend doesn't support "
138  "VIRTIO_NET_F_MRG_RXBUF feature");
139  goto error;
140  }
141 
142  if ((vif->remote_features & VIRTIO_FEATURE (VIRTIO_RING_F_INDIRECT_DESC)) ==
143  0)
144  {
145  args->rv = VNET_API_ERROR_UNSUPPORTED;
146  args->error = clib_error_return (0, "vhost-net backend doesn't support "
147  "VIRTIO_RING_F_INDIRECT_DESC feature");
148  goto error;
149  }
150 
151  if ((vif->remote_features & VIRTIO_FEATURE (VIRTIO_F_VERSION_1)) == 0)
152  {
153  args->rv = VNET_API_ERROR_UNSUPPORTED;
154  args->error = clib_error_return (0, "vhost-net backend doesn't support "
155  "VIRTIO_F_VERSION_1 features");
156  goto error;
157  }
158 
159  vif->features |= VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF);
160  vif->features |= VIRTIO_FEATURE (VIRTIO_F_VERSION_1);
161  vif->features |= VIRTIO_FEATURE (VIRTIO_RING_F_INDIRECT_DESC);
162 
164 
165  _IOCTL (vif->fd, VHOST_SET_FEATURES, &vif->features);
166 
167  if ((vif->tap_fd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0)
168  {
169  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
170  args->error = clib_error_return_unix (0, "open '/dev/net/tun'");
171  goto error;
172  }
173 
174  ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR;
175  _IOCTL (vif->tap_fd, TUNSETIFF, (void *) &ifr);
176  vif->ifindex = if_nametoindex (ifr.ifr_ifrn.ifrn_name);
177 
178  if (!args->host_if_name)
179  host_if_name = ifr.ifr_ifrn.ifrn_name;
180  else
181  host_if_name = (char *) args->host_if_name;
182 
183  unsigned int offload = 0;
184  hdrsz = sizeof (struct virtio_net_hdr_v1);
185  if (args->tap_flags & TAP_FLAG_GSO)
186  {
187  offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
188  vif->gso_enabled = 1;
189  }
190  else
191  {
192  vif->gso_enabled = 0;
193  }
194 
195  _IOCTL (vif->tap_fd, TUNSETOFFLOAD, offload);
196  _IOCTL (vif->tap_fd, TUNSETVNETHDRSZ, &hdrsz);
197  _IOCTL (vif->fd, VHOST_SET_OWNER, 0);
198 
199  /* if namespace is specified, all further netlink messages should be excuted
200  after we change our net namespace */
201  if (args->host_namespace)
202  {
203  old_netns_fd = open ("/proc/self/ns/net", O_RDONLY);
204  if ((fd = open_netns_fd ((char *) args->host_namespace)) == -1)
205  {
206  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
207  args->error = clib_error_return_unix (0, "open_netns_fd '%s'",
208  args->host_namespace);
209  goto error;
210  }
211  args->error = vnet_netlink_set_link_netns (vif->ifindex, fd,
212  host_if_name);
213  if (args->error)
214  {
215  args->rv = VNET_API_ERROR_NETLINK_ERROR;
216  goto error;
217  }
218  if (setns (fd, CLONE_NEWNET) == -1)
219  {
220  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
221  args->error = clib_error_return_unix (0, "setns '%s'",
222  args->host_namespace);
223  goto error;
224  }
225  if ((vif->ifindex = if_nametoindex (host_if_name)) == 0)
226  {
227  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
228  args->error = clib_error_return_unix (0, "if_nametoindex '%s'",
229  host_if_name);
230  goto error;
231  }
232  }
233  else
234  {
235  if (host_if_name)
236  {
238  host_if_name);
239  if (args->error)
240  {
241  args->rv = VNET_API_ERROR_NETLINK_ERROR;
242  goto error;
243  }
244  }
245  }
246 
248  {
250  args->host_mac_addr);
251  if (args->error)
252  {
253  args->rv = VNET_API_ERROR_NETLINK_ERROR;
254  goto error;
255  }
256  }
257 
258  if (args->host_bridge)
259  {
261  (char *) args->host_bridge);
262  if (args->error)
263  {
264  args->rv = VNET_API_ERROR_NETLINK_ERROR;
265  goto error;
266  }
267  }
268 
269 
270  if (args->host_ip4_prefix_len)
271  {
273  &args->host_ip4_addr,
274  args->host_ip4_prefix_len);
275  if (args->error)
276  {
277  args->rv = VNET_API_ERROR_NETLINK_ERROR;
278  goto error;
279  }
280  }
281 
282  if (args->host_ip6_prefix_len)
283  {
285  &args->host_ip6_addr,
286  args->host_ip6_prefix_len);
287  if (args->error)
288  {
289  args->rv = VNET_API_ERROR_NETLINK_ERROR;
290  goto error;
291  }
292  }
293 
294  args->error = vnet_netlink_set_link_state (vif->ifindex, 1 /* UP */ );
295  if (args->error)
296  {
297  args->rv = VNET_API_ERROR_NETLINK_ERROR;
298  goto error;
299  }
300 
301  if (args->host_ip4_gw_set)
302  {
303  args->error = vnet_netlink_add_ip4_route (0, 0, &args->host_ip4_gw);
304  if (args->error)
305  {
306  args->rv = VNET_API_ERROR_NETLINK_ERROR;
307  goto error;
308  }
309  }
310 
311  if (args->host_ip6_gw_set)
312  {
313  args->error = vnet_netlink_add_ip6_route (0, 0, &args->host_ip6_gw);
314  if (args->error)
315  {
316  args->rv = VNET_API_ERROR_NETLINK_ERROR;
317  goto error;
318  }
319  }
320 
321  /* switch back to old net namespace */
322  if (args->host_namespace)
323  {
324  if (setns (old_netns_fd, CLONE_NEWNET) == -1)
325  {
326  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
327  args->error = clib_error_return_unix (0, "setns '%s'",
328  args->host_namespace);
329  goto error;
330  }
331  }
332 
333  if (args->host_mtu_set)
334  {
335  args->error =
337  if (args->error)
338  {
339  args->rv = VNET_API_ERROR_NETLINK_ERROR;
340  goto error;
341  }
342  }
343  else if (tm->host_mtu_size != 0)
344  {
345  args->error =
347  if (args->error)
348  {
349  args->rv = VNET_API_ERROR_NETLINK_ERROR;
350  goto error;
351  }
352  args->host_mtu_set = 1;
353  args->host_mtu_size = tm->host_mtu_size;
354  }
355 
356  /* Set vhost memory table */
357  i = sizeof (struct vhost_memory) + sizeof (struct vhost_memory_region);
358  vhost_mem = clib_mem_alloc (i);
359  clib_memset (vhost_mem, 0, i);
360  vhost_mem->nregions = 1;
361  vhost_mem->regions[0].memory_size = (1ULL << 47) - 4096;
362  _IOCTL (vif->fd, VHOST_SET_MEM_TABLE, vhost_mem);
363 
364  if ((args->error =
365  virtio_vring_init (vm, vif, RX_QUEUE (0), args->rx_ring_sz)))
366  {
367  args->rv = VNET_API_ERROR_INIT_FAILED;
368  goto error;
369  }
370  vif->num_rxqs = 1;
371 
372  if ((args->error =
373  virtio_vring_init (vm, vif, TX_QUEUE (0), args->tx_ring_sz)))
374  {
375  args->rv = VNET_API_ERROR_INIT_FAILED;
376  goto error;
377  }
378  vif->num_txqs = 1;
379 
380  if (!args->mac_addr_set)
382 
383  clib_memcpy (vif->mac_addr, args->mac_addr, 6);
384 
385  vif->host_if_name = format (0, "%s%c", host_if_name, 0);
386  vif->net_ns = format (0, "%s%c", args->host_namespace, 0);
387  vif->host_bridge = format (0, "%s%c", args->host_bridge, 0);
388  vif->host_mtu_size = args->host_mtu_size;
389  clib_memcpy (vif->host_mac_addr, args->host_mac_addr, 6);
392  if (args->host_ip4_prefix_len)
393  clib_memcpy (&vif->host_ip4_addr, &args->host_ip4_addr, 4);
394  if (args->host_ip6_prefix_len)
395  clib_memcpy (&vif->host_ip6_addr, &args->host_ip6_addr, 16);
396 
397  vif->type = VIRTIO_IF_TYPE_TAP;
399  vif->dev_instance,
400  vif->mac_addr,
401  &vif->hw_if_index,
403  if (args->error)
404  {
405  args->rv = VNET_API_ERROR_INVALID_REGISTRATION;
406  goto error;
407  }
408 
409  tm->tap_ids = clib_bitmap_set (tm->tap_ids, vif->id, 1);
410  sw = vnet_get_hw_sw_interface (vnm, vif->hw_if_index);
411  vif->sw_if_index = sw->sw_if_index;
412  args->sw_if_index = vif->sw_if_index;
413  args->rv = 0;
414  hw = vnet_get_hw_interface (vnm, vif->hw_if_index);
416  if (args->tap_flags & TAP_FLAG_GSO)
417  {
420  }
422  virtio_input_node.index);
426  vif->per_interface_next_index = ~0;
427  virtio_vring_set_numa_node (vm, vif, RX_QUEUE (0));
428  vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP;
431  vif->cxq_vring = NULL;
432 
433  goto done;
434 
435 error:
436  if (err)
437  {
438  ASSERT (args->error == 0);
439  args->error = err;
440  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
441  }
442  if (vif->tap_fd != -1)
443  close (vif->tap_fd);
444  if (vif->fd != -1)
445  close (vif->fd);
447  RX_QUEUE (i));
449  TX_QUEUE (i));
450  vec_free (vif->rxq_vrings);
451  vec_free (vif->txq_vrings);
452 
453  vec_free (vif->host_if_name);
454  vec_free (vif->net_ns);
455  vec_free (vif->host_bridge);
456 
457  clib_memset (vif, 0, sizeof (virtio_if_t));
458  pool_put (vim->interfaces, vif);
459 
460 done:
461  if (vhost_mem)
462  clib_mem_free (vhost_mem);
463  if (old_netns_fd != -1)
464  close (old_netns_fd);
465  if (fd != -1)
466  close (fd);
467 }
468 
469 int
471 {
472  vnet_main_t *vnm = vnet_get_main ();
473  virtio_main_t *mm = &virtio_main;
474  tap_main_t *tm = &tap_main;
475  int i;
476  virtio_if_t *vif;
478 
479  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
480  if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
481  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
482 
483  vif = pool_elt_at_index (mm->interfaces, hw->dev_instance);
484 
485  if (vif->type != VIRTIO_IF_TYPE_TAP)
486  return VNET_API_ERROR_INVALID_INTERFACE;
487 
488  /* decrement if this was a GSO interface */
491 
492  /* bring down the interface */
496 
498  vif->hw_if_index = ~0;
499 
500  if (vif->tap_fd != -1)
501  close (vif->tap_fd);
502  if (vif->fd != -1)
503  close (vif->fd);
504 
506  RX_QUEUE (i));
508  TX_QUEUE (i));
509  vec_free (vif->rxq_vrings);
510  vec_free (vif->txq_vrings);
511 
512  vec_free (vif->host_if_name);
513  vec_free (vif->net_ns);
514  vec_free (vif->host_bridge);
515 
516  tm->tap_ids = clib_bitmap_set (tm->tap_ids, vif->id, 0);
517  clib_memset (vif, 0, sizeof (*vif));
518  pool_put (mm->interfaces, vif);
519 
520  return 0;
521 }
522 
523 int
525 {
526  vnet_main_t *vnm = vnet_get_main ();
527  virtio_main_t *mm = &virtio_main;
528  virtio_if_t *vif;
530  clib_error_t *err = 0;
531 
532  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
533 
534  if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
535  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
536 
537  vif = pool_elt_at_index (mm->interfaces, hw->dev_instance);
538 
539  const unsigned int gso_on = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
540  const unsigned int gso_off = 0;
541  unsigned int offload = enable_disable ? gso_on : gso_off;
542  _IOCTL (vif->tap_fd, TUNSETOFFLOAD, offload);
543  vif->gso_enabled = enable_disable ? 1 : 0;
544  if (enable_disable)
545  {
547  {
550  }
551  }
552  else
553  {
555  {
558  }
559  }
560 
561 error:
562  if (err)
563  {
564  clib_warning ("Error %s gso on sw_if_index %d",
565  enable_disable ? "enabling" : "disabling", sw_if_index);
566  return VNET_API_ERROR_SYSCALL_ERROR_3;
567  }
568  return 0;
569 }
570 
571 int
573 {
574  vnet_main_t *vnm = vnet_get_main ();
575  virtio_main_t *mm = &virtio_main;
576  virtio_if_t *vif;
577  virtio_vring_t *vring;
579  tap_interface_details_t *r_tapids = NULL;
580  tap_interface_details_t *tapid = NULL;
581 
582  /* *INDENT-OFF* */
583  pool_foreach (vif, mm->interfaces,
584  if (vif->type != VIRTIO_IF_TYPE_TAP)
585  continue;
586  vec_add2(r_tapids, tapid, 1);
587  clib_memset (tapid, 0, sizeof (*tapid));
588  tapid->id = vif->id;
589  tapid->sw_if_index = vif->sw_if_index;
590  hi = vnet_get_hw_interface (vnm, vif->hw_if_index);
591  clib_memcpy(tapid->dev_name, hi->name,
592  MIN (ARRAY_LEN (tapid->dev_name) - 1,
593  strlen ((const char *) hi->name)));
594  vring = vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS(0));
595  tapid->rx_ring_sz = vring->size;
596  vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS(0));
597  tapid->tx_ring_sz = vring->size;
598  clib_memcpy(tapid->host_mac_addr, vif->host_mac_addr, 6);
599  if (vif->host_if_name)
600  {
602  MIN (ARRAY_LEN (tapid->host_if_name) - 1,
603  strlen ((const char *) vif->host_if_name)));
604  }
605  if (vif->net_ns)
606  {
607  clib_memcpy(tapid->host_namespace, vif->net_ns,
608  MIN (ARRAY_LEN (tapid->host_namespace) - 1,
609  strlen ((const char *) vif->net_ns)));
610  }
611  if (vif->host_bridge)
612  {
613  clib_memcpy(tapid->host_bridge, vif->host_bridge,
614  MIN (ARRAY_LEN (tapid->host_bridge) - 1,
615  strlen ((const char *) vif->host_bridge)));
616  }
617  if (vif->host_ip4_prefix_len)
618  clib_memcpy(tapid->host_ip4_addr, &vif->host_ip4_addr, 4);
620  if (vif->host_ip6_prefix_len)
621  clib_memcpy(tapid->host_ip6_addr, &vif->host_ip6_addr, 16);
623  tapid->host_mtu_size = vif->host_mtu_size;
624  );
625  /* *INDENT-ON* */
626 
627  *out_tapids = r_tapids;
628 
629  return 0;
630 }
631 
632 static clib_error_t *
634 {
635  tap_main_t *tm = &tap_main;
636 
638  {
639  if (unformat (input, "host-mtu %d", &tm->host_mtu_size))
640  ;
641  else
642  return clib_error_return (0, "unknown input `%U'",
643  format_unformat_error, input);
644  }
645 
646  return 0;
647 }
648 
649 /* tap { host-mtu <size> } configuration. */
651 
652 static clib_error_t *
654 {
655  tap_main_t *tm = &tap_main;
656  clib_error_t *error = 0;
657 
658  tm->log_default = vlib_log_register_class ("tap", 0);
659  vlib_log_debug (tm->log_default, "initialized");
660 
661  tm->host_mtu_size = 0;
662 
663  return error;
664 }
665 
667 
668 /*
669  * fd.io coding-style-patch-verification: ON
670  *
671  * Local Variables:
672  * eval: (c-set-style "gnu")
673  * End:
674  */
u32 per_interface_next_index
Definition: virtio.h:150
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:176
vmrglw vmrglh hi
#define vec_foreach_index(var, v)
Iterate over vector indices.
uword * tap_ids
Definition: tap.h:80
int host_mtu_size
Definition: tap.h:83
#define TAP_FLAG_GSO
Definition: tap.h:33
vlib_node_registration_t virtio_input_node
(constructor) VLIB_REGISTER_NODE (virtio_input_node)
Definition: node.c:397
void virtio_set_net_hdr_size(virtio_if_t *vif)
Definition: virtio.c:257
virtio_if_t * interfaces
Definition: virtio.h:192
u32 flags
Definition: vhost_user.h:141
static u32 virtio_eth_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
Definition: tap.c:52
vlib_log_class_t log_default
Definition: tap.h:77
ip4_address_t host_ip4_addr
Definition: virtio.h:177
u8 host_if_name[64]
Definition: tap.h:64
u8 host_namespace[64]
Definition: tap.h:65
ip4_address_t host_ip4_addr
Definition: tap.h:38
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:324
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
int tap_gso_enable_disable(vlib_main_t *vm, u32 sw_if_index, int enable_disable)
Definition: tap.c:524
vnet_interface_main_t interface_main
Definition: vnet.h:56
int gso_enabled
Definition: virtio.h:182
u32 host_mtu_size
Definition: virtio.h:181
u32 dev_instance
Definition: virtio.h:139
#define NULL
Definition: clib.h:58
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
u8 host_ip6_prefix_len
Definition: tap.h:43
vnet_device_class_t virtio_device_class
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:560
int i
void virtio_vring_set_numa_node(vlib_main_t *vm, virtio_if_t *vif, u32 idx)
Definition: virtio.c:241
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
Definition: bitmap.h:167
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:236
int tap_dump_ifs(tap_interface_details_t **out_tapids)
Definition: tap.c:572
u8 host_ip4_gw_set
Definition: tap.h:41
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:218
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define clib_memcpy(d, s, n)
Definition: string.h:180
u8 host_bridge[64]
Definition: tap.h:66
u8 host_ip6_addr[16]
Definition: tap.h:69
u64 features
Definition: virtio.h:163
u32 hw_if_index
Definition: virtio.h:140
u8 host_mac_addr[6]
Definition: tap.h:63
u8 host_ip6_prefix_len
Definition: virtio.h:180
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
vl_api_interface_index_t sw_if_index
Definition: gre.api:50
#define TX_QUEUE_ACCESS(X)
Definition: virtio.h:80
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u8 * host_bridge
Definition: virtio.h:175
int ifindex
Definition: virtio.h:183
vnet_hw_interface_flags_t flags
Definition: interface.h:505
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
int tap_delete_if(vlib_main_t *vm, u32 sw_if_index)
Definition: tap.c:470
#define clib_error_return(e, args...)
Definition: error.h:99
u8 host_mac_addr[6]
Definition: tap.h:36
unsigned int u32
Definition: types.h:88
#define vlib_log_debug(...)
Definition: log.h:106
#define MIN(x, y)
Definition: node.h:31
u32 id
Definition: virtio.h:147
u16 num_txqs
Definition: virtio.h:170
u8 host_ip4_addr[4]
Definition: tap.h:67
#define TX_QUEUE(X)
Definition: virtio.h:78
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
int tap_fd
Definition: virtio.h:158
struct _unformat_input_t unformat_input_t
#define clib_error_return_unix(e, args...)
Definition: error.h:102
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:182
ip4_address_t host_ip4_gw
Definition: tap.h:40
ip6_address_t host_ip6_addr
Definition: tap.h:42
u8 host_ip4_prefix_len
Definition: tap.h:39
u16 num_rxqs
Definition: virtio.h:169
virtio_vring_t * rxq_vrings
Definition: virtio.h:161
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
vlib_main_t * vm
Definition: buffer.c:312
#define TAP_MAX_INSTANCE
Definition: tap.c:78
static int open_netns_fd(char *netns)
Definition: tap.c:61
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
u32 host_mtu_size
Definition: tap.h:47
ip6_address_t host_ip6_addr
Definition: virtio.h:179
static vnet_hw_interface_t * vnet_get_sup_hw_interface_api_visible_or_null(vnet_main_t *vnm, u32 sw_if_index)
#define clib_warning(format, args...)
Definition: error.h:59
u8 * net_ns
Definition: virtio.h:174
u8 mac_addr[6]
Definition: virtio.h:172
u32 flags
Definition: virtio.h:137
#define ARRAY_LEN(x)
Definition: clib.h:62
static uword clib_bitmap_get(uword *ai, uword i)
Gets the ith bit value from a bitmap.
Definition: bitmap.h:197
u8 * host_bridge
Definition: tap.h:37
virtio_if_type_t type
Definition: virtio.h:144
#define ASSERT(truth)
void vnet_hw_interface_assign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, uword thread_index)
Definition: devices.c:139
u64 remote_features
Definition: virtio.h:163
ip6_address_t host_ip6_gw
Definition: tap.h:44
#define VIRTIO_FEATURE(X)
Definition: virtio.h:76
clib_error_t * virtio_vring_init(vlib_main_t *vm, virtio_if_t *vif, u16 idx, u16 sz)
Definition: virtio.c:65
u8 * host_if_name
Definition: tap.h:35
u8 host_mac_addr[6]
Definition: virtio.h:176
static void clib_mem_free(void *p)
Definition: mem.h:226
unsigned int if_nametoindex(const char *ifname)
static void * clib_mem_alloc(uword size)
Definition: mem.h:153
virtio_main_t virtio_main
Definition: virtio.c:37
u8 host_ip6_gw_set
Definition: tap.h:45
void tap_create_if(vlib_main_t *vm, tap_create_if_args_t *args)
Definition: tap.c:81
#define RX_QUEUE_ACCESS(X)
Definition: virtio.h:81
tap_main_t tap_main
Definition: tap.c:42
static void ethernet_mac_address_generate(u8 *mac)
Definition: mac_address.h:74
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, const u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
Definition: interface.c:278
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:501
int fd
Definition: virtio.h:153
u8 mac_addr[6]
Definition: tap.h:29
Definition: tap.h:74
clib_error_t * error
Definition: tap.h:51
u8 host_ip4_prefix_len
Definition: virtio.h:178
int vnet_hw_interface_unassign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.c:188
u32 sw_if_index
Definition: virtio.h:141
virtio_vring_t * cxq_vring
Definition: virtio.h:184
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static int ethernet_mac_address_is_zero(const u8 *mac)
Definition: mac_address.h:68
clib_error_t * virtio_vring_free_rx(vlib_main_t *vm, virtio_if_t *vif, u32 idx)
Definition: virtio.c:170
TAP interface details struct.
Definition: tap.h:55
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, vnet_sw_interface_flags_t flags)
Definition: interface.c:510
static clib_error_t * tap_mtu_config(vlib_main_t *vm, unformat_input_t *input)
Definition: tap.c:633
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:253
u8 * host_namespace
Definition: tap.h:34
static uword clib_bitmap_first_clear(uword *ai)
Return the lowest numbered clear bit in a bitmap.
Definition: bitmap.h:445
#define RX_QUEUE(X)
Definition: virtio.h:79
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: devices.h:79
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
virtio_vring_t * txq_vrings
Definition: virtio.h:162
static clib_error_t * tap_init(vlib_main_t *vm)
Definition: tap.c:653
u8 * host_if_name
Definition: virtio.h:173