FD.io VPP  v19.08.3-2-gbabecb413
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/physmem.h>
35 #include <vlib/unix/unix.h>
36 #include <vnet/ethernet/ethernet.h>
37 #include <vnet/ip/ip4_packet.h>
38 #include <vnet/ip/ip6_packet.h>
39 #include <vnet/devices/netlink.h>
41 #include <vnet/devices/tap/tap.h>
42 
44 
45 #define _IOCTL(fd,a,...) \
46  if (ioctl (fd, a, __VA_ARGS__) < 0) \
47  { \
48  err = clib_error_return_unix (0, "ioctl(" #a ")"); \
49  goto error; \
50  }
51 
52 static u32
54  u32 flags)
55 {
56  /* nothing for now */
57  //TODO On MTU change call vnet_netlink_set_if_mtu
58  return 0;
59 }
60 
61 static int
62 open_netns_fd (char *netns)
63 {
64  u8 *s = 0;
65  int fd;
66 
67  if (strncmp (netns, "pid:", 4) == 0)
68  s = format (0, "/proc/%u/ns/net%c", atoi (netns + 4), 0);
69  else if (netns[0] == '/')
70  s = format (0, "%s%c", netns, 0);
71  else
72  s = format (0, "/var/run/netns/%s%c", netns, 0);
73 
74  fd = open ((char *) s, O_RDONLY);
75  vec_free (s);
76  return fd;
77 }
78 
79 #define TAP_MAX_INSTANCE 1024
80 
81 void
83 {
85  vnet_main_t *vnm = vnet_get_main ();
86  virtio_main_t *vim = &virtio_main;
87  tap_main_t *tm = &tap_main;
90  int i;
91  int old_netns_fd = -1;
92  struct ifreq ifr;
93  size_t hdrsz;
94  struct vhost_memory *vhost_mem = 0;
95  virtio_if_t *vif = 0;
96  clib_error_t *err = 0;
97  int fd = -1;
98  char *host_if_name = 0;
99 
100  if (args->id != ~0)
101  {
102  if (clib_bitmap_get (tm->tap_ids, args->id))
103  {
104  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
105  args->error = clib_error_return (0, "interface already exists");
106  return;
107  }
108  }
109  else
110  {
111  args->id = clib_bitmap_first_clear (tm->tap_ids);
112  }
113 
114  if (args->id > TAP_MAX_INSTANCE)
115  {
116  args->rv = VNET_API_ERROR_UNSPECIFIED;
117  args->error = clib_error_return (0, "cannot find free interface id");
118  return;
119  }
120 
121  clib_memset (&ifr, 0, sizeof (ifr));
122  pool_get (vim->interfaces, vif);
123  vif->dev_instance = vif - vim->interfaces;
124  vif->tap_fd = -1;
125  vif->id = args->id;
126 
127  if ((vif->fd = open ("/dev/vhost-net", O_RDWR | O_NONBLOCK)) < 0)
128  {
129  args->rv = VNET_API_ERROR_SYSCALL_ERROR_1;
130  args->error = clib_error_return_unix (0, "open '/dev/vhost-net'");
131  goto error;
132  }
133 
134  _IOCTL (vif->fd, VHOST_GET_FEATURES, &vif->remote_features);
135 
136  if ((vif->remote_features & VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF)) == 0)
137  {
138  args->rv = VNET_API_ERROR_UNSUPPORTED;
139  args->error = clib_error_return (0, "vhost-net backend doesn't support "
140  "VIRTIO_NET_F_MRG_RXBUF feature");
141  goto error;
142  }
143 
144  if ((vif->remote_features & VIRTIO_FEATURE (VIRTIO_RING_F_INDIRECT_DESC)) ==
145  0)
146  {
147  args->rv = VNET_API_ERROR_UNSUPPORTED;
148  args->error = clib_error_return (0, "vhost-net backend doesn't support "
149  "VIRTIO_RING_F_INDIRECT_DESC feature");
150  goto error;
151  }
152 
153  if ((vif->remote_features & VIRTIO_FEATURE (VIRTIO_F_VERSION_1)) == 0)
154  {
155  args->rv = VNET_API_ERROR_UNSUPPORTED;
156  args->error = clib_error_return (0, "vhost-net backend doesn't support "
157  "VIRTIO_F_VERSION_1 features");
158  goto error;
159  }
160 
161  vif->features |= VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF);
162  vif->features |= VIRTIO_FEATURE (VIRTIO_F_VERSION_1);
163  vif->features |= VIRTIO_FEATURE (VIRTIO_RING_F_INDIRECT_DESC);
164 
166 
167  _IOCTL (vif->fd, VHOST_SET_FEATURES, &vif->features);
168 
169  if ((vif->tap_fd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0)
170  {
171  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
172  args->error = clib_error_return_unix (0, "open '/dev/net/tun'");
173  goto error;
174  }
175 
176  ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR;
177  _IOCTL (vif->tap_fd, TUNSETIFF, (void *) &ifr);
178  vif->ifindex = if_nametoindex (ifr.ifr_ifrn.ifrn_name);
179 
180  if (!args->host_if_name)
181  host_if_name = ifr.ifr_ifrn.ifrn_name;
182  else
183  host_if_name = (char *) args->host_if_name;
184 
185  unsigned int offload = 0;
186  hdrsz = sizeof (struct virtio_net_hdr_v1);
187  if (args->tap_flags & TAP_FLAG_GSO)
188  {
189  offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
190  vif->gso_enabled = 1;
191  }
192  else
193  {
194  vif->gso_enabled = 0;
195  }
196 
197  _IOCTL (vif->tap_fd, TUNSETOFFLOAD, offload);
198  _IOCTL (vif->tap_fd, TUNSETVNETHDRSZ, &hdrsz);
199  _IOCTL (vif->fd, VHOST_SET_OWNER, 0);
200 
201  /* if namespace is specified, all further netlink messages should be excuted
202  after we change our net namespace */
203  if (args->host_namespace)
204  {
205  old_netns_fd = open ("/proc/self/ns/net", O_RDONLY);
206  if ((fd = open_netns_fd ((char *) args->host_namespace)) == -1)
207  {
208  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
209  args->error = clib_error_return_unix (0, "open_netns_fd '%s'",
210  args->host_namespace);
211  goto error;
212  }
213  args->error = vnet_netlink_set_link_netns (vif->ifindex, fd,
214  host_if_name);
215  if (args->error)
216  {
217  args->rv = VNET_API_ERROR_NETLINK_ERROR;
218  goto error;
219  }
220  if (setns (fd, CLONE_NEWNET) == -1)
221  {
222  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
223  args->error = clib_error_return_unix (0, "setns '%s'",
224  args->host_namespace);
225  goto error;
226  }
227  if ((vif->ifindex = if_nametoindex (host_if_name)) == 0)
228  {
229  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
230  args->error = clib_error_return_unix (0, "if_nametoindex '%s'",
231  host_if_name);
232  goto error;
233  }
234  }
235  else
236  {
237  if (host_if_name)
238  {
240  host_if_name);
241  if (args->error)
242  {
243  args->rv = VNET_API_ERROR_NETLINK_ERROR;
244  goto error;
245  }
246  }
247  }
248 
252  args->host_mac_addr);
253  if (args->error)
254  {
255  args->rv = VNET_API_ERROR_NETLINK_ERROR;
256  goto error;
257  }
258 
259  if (args->host_bridge)
260  {
262  (char *) args->host_bridge);
263  if (args->error)
264  {
265  args->rv = VNET_API_ERROR_NETLINK_ERROR;
266  goto error;
267  }
268  }
269 
270 
271  if (args->host_ip4_prefix_len)
272  {
274  &args->host_ip4_addr,
275  args->host_ip4_prefix_len);
276  if (args->error)
277  {
278  args->rv = VNET_API_ERROR_NETLINK_ERROR;
279  goto error;
280  }
281  }
282 
283  if (args->host_ip6_prefix_len)
284  {
286  &args->host_ip6_addr,
287  args->host_ip6_prefix_len);
288  if (args->error)
289  {
290  args->rv = VNET_API_ERROR_NETLINK_ERROR;
291  goto error;
292  }
293  }
294 
295  args->error = vnet_netlink_set_link_state (vif->ifindex, 1 /* UP */ );
296  if (args->error)
297  {
298  args->rv = VNET_API_ERROR_NETLINK_ERROR;
299  goto error;
300  }
301 
302  if (args->host_ip4_gw_set)
303  {
304  args->error = vnet_netlink_add_ip4_route (0, 0, &args->host_ip4_gw);
305  if (args->error)
306  {
307  args->rv = VNET_API_ERROR_NETLINK_ERROR;
308  goto error;
309  }
310  }
311 
312  if (args->host_ip6_gw_set)
313  {
314  args->error = vnet_netlink_add_ip6_route (0, 0, &args->host_ip6_gw);
315  if (args->error)
316  {
317  args->rv = VNET_API_ERROR_NETLINK_ERROR;
318  goto error;
319  }
320  }
321 
322  if (args->host_mtu_set)
323  {
324  args->error =
326  if (args->error)
327  {
328  args->rv = VNET_API_ERROR_NETLINK_ERROR;
329  goto error;
330  }
331  }
332  else if (tm->host_mtu_size != 0)
333  {
334  args->error =
336  if (args->error)
337  {
338  args->rv = VNET_API_ERROR_NETLINK_ERROR;
339  goto error;
340  }
341  args->host_mtu_set = 1;
342  args->host_mtu_size = tm->host_mtu_size;
343  }
344 
345  /* switch back to old net namespace */
346  if (args->host_namespace)
347  {
348  if (setns (old_netns_fd, CLONE_NEWNET) == -1)
349  {
350  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
351  args->error = clib_error_return_unix (0, "setns '%s'",
352  args->host_namespace);
353  goto error;
354  }
355  }
356 
357  /* Set vhost memory table */
358  i = sizeof (struct vhost_memory) + sizeof (struct vhost_memory_region);
359  vhost_mem = clib_mem_alloc (i);
360  clib_memset (vhost_mem, 0, i);
361  vhost_mem->nregions = 1;
362  vhost_mem->regions[0].memory_size = vpm->max_size;
363  vhost_mem->regions[0].guest_phys_addr = vpm->base_addr;
364  vhost_mem->regions[0].userspace_addr =
365  vhost_mem->regions[0].guest_phys_addr;
366  _IOCTL (vif->fd, VHOST_SET_MEM_TABLE, vhost_mem);
367 
368  if ((args->error =
369  virtio_vring_init (vm, vif, RX_QUEUE (0), args->rx_ring_sz)))
370  {
371  args->rv = VNET_API_ERROR_INIT_FAILED;
372  goto error;
373  }
374  vif->num_rxqs = 1;
375 
376  if ((args->error =
377  virtio_vring_init (vm, vif, TX_QUEUE (0), args->tx_ring_sz)))
378  {
379  args->rv = VNET_API_ERROR_INIT_FAILED;
380  goto error;
381  }
382  vif->num_txqs = 1;
383 
384  if (!args->mac_addr_set)
386 
387  clib_memcpy (vif->mac_addr, args->mac_addr, 6);
388 
389  vif->host_if_name = format (0, "%s%c", host_if_name, 0);
390  vif->net_ns = format (0, "%s%c", args->host_namespace, 0);
391  vif->host_bridge = format (0, "%s%c", args->host_bridge, 0);
392  vif->host_mtu_size = args->host_mtu_size;
393  clib_memcpy (vif->host_mac_addr, args->host_mac_addr, 6);
396  if (args->host_ip4_prefix_len)
397  clib_memcpy (&vif->host_ip4_addr, &args->host_ip4_addr, 4);
398  if (args->host_ip6_prefix_len)
399  clib_memcpy (&vif->host_ip6_addr, &args->host_ip6_addr, 16);
400 
401  vif->type = VIRTIO_IF_TYPE_TAP;
403  vif->dev_instance,
404  vif->mac_addr,
405  &vif->hw_if_index,
407  if (args->error)
408  {
409  args->rv = VNET_API_ERROR_INVALID_REGISTRATION;
410  goto error;
411  }
412 
413  tm->tap_ids = clib_bitmap_set (tm->tap_ids, vif->id, 1);
414  sw = vnet_get_hw_sw_interface (vnm, vif->hw_if_index);
415  vif->sw_if_index = sw->sw_if_index;
416  args->sw_if_index = vif->sw_if_index;
417  args->rv = 0;
418  hw = vnet_get_hw_interface (vnm, vif->hw_if_index);
420  if (args->tap_flags & TAP_FLAG_GSO)
421  {
424  }
426  virtio_input_node.index);
430  vif->per_interface_next_index = ~0;
431  virtio_vring_set_numa_node (vm, vif, RX_QUEUE (0));
432  vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP;
435  vif->cxq_vring = NULL;
436 
437  goto done;
438 
439 error:
440  if (err)
441  {
442  ASSERT (args->error == 0);
443  args->error = err;
444  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
445  }
446  if (vif->tap_fd != -1)
447  close (vif->tap_fd);
448  if (vif->fd != -1)
449  close (vif->fd);
451  RX_QUEUE (i));
453  TX_QUEUE (i));
454  vec_free (vif->rxq_vrings);
455  vec_free (vif->txq_vrings);
456 
457  vec_free (vif->host_if_name);
458  vec_free (vif->net_ns);
459  vec_free (vif->host_bridge);
460 
461  clib_memset (vif, 0, sizeof (virtio_if_t));
462  pool_put (vim->interfaces, vif);
463 
464 done:
465  if (vhost_mem)
466  clib_mem_free (vhost_mem);
467  if (old_netns_fd != -1)
468  close (old_netns_fd);
469  if (fd != -1)
470  close (fd);
471 }
472 
473 int
475 {
476  vnet_main_t *vnm = vnet_get_main ();
477  virtio_main_t *mm = &virtio_main;
478  tap_main_t *tm = &tap_main;
479  int i;
480  virtio_if_t *vif;
482 
483  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
484  if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
485  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
486 
487  vif = pool_elt_at_index (mm->interfaces, hw->dev_instance);
488 
489  if (vif->type != VIRTIO_IF_TYPE_TAP)
490  return VNET_API_ERROR_INVALID_INTERFACE;
491 
492  /* decrement if this was a GSO interface */
495 
496  /* bring down the interface */
500 
502  vif->hw_if_index = ~0;
503 
504  if (vif->tap_fd != -1)
505  close (vif->tap_fd);
506  if (vif->fd != -1)
507  close (vif->fd);
508 
510  RX_QUEUE (i));
512  TX_QUEUE (i));
513  vec_free (vif->rxq_vrings);
514  vec_free (vif->txq_vrings);
515 
516  vec_free (vif->host_if_name);
517  vec_free (vif->net_ns);
518  vec_free (vif->host_bridge);
519 
520  tm->tap_ids = clib_bitmap_set (tm->tap_ids, vif->id, 0);
521  clib_memset (vif, 0, sizeof (*vif));
522  pool_put (mm->interfaces, vif);
523 
524  return 0;
525 }
526 
527 int
529 {
530  vnet_main_t *vnm = vnet_get_main ();
531  virtio_main_t *mm = &virtio_main;
532  virtio_if_t *vif;
534  clib_error_t *err = 0;
535 
536  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
537 
538  if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
539  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
540 
541  vif = pool_elt_at_index (mm->interfaces, hw->dev_instance);
542 
543  const unsigned int gso_on = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
544  const unsigned int gso_off = 0;
545  unsigned int offload = enable_disable ? gso_on : gso_off;
546  _IOCTL (vif->tap_fd, TUNSETOFFLOAD, offload);
547  vif->gso_enabled = enable_disable ? 1 : 0;
548  if (enable_disable)
549  {
551  {
554  }
555  }
556  else
557  {
559  {
562  }
563  }
564 
565 error:
566  if (err)
567  {
568  clib_warning ("Error %s gso on sw_if_index %d",
569  enable_disable ? "enabling" : "disabling", sw_if_index);
570  return VNET_API_ERROR_SYSCALL_ERROR_3;
571  }
572  return 0;
573 }
574 
575 int
577 {
578  vnet_main_t *vnm = vnet_get_main ();
579  virtio_main_t *mm = &virtio_main;
580  virtio_if_t *vif;
581  virtio_vring_t *vring;
583  tap_interface_details_t *r_tapids = NULL;
584  tap_interface_details_t *tapid = NULL;
585 
586  /* *INDENT-OFF* */
587  pool_foreach (vif, mm->interfaces,
588  if (vif->type != VIRTIO_IF_TYPE_TAP)
589  continue;
590  vec_add2(r_tapids, tapid, 1);
591  clib_memset (tapid, 0, sizeof (*tapid));
592  tapid->id = vif->id;
593  tapid->sw_if_index = vif->sw_if_index;
594  hi = vnet_get_hw_interface (vnm, vif->hw_if_index);
595  clib_memcpy(tapid->dev_name, hi->name,
596  MIN (ARRAY_LEN (tapid->dev_name) - 1,
597  strlen ((const char *) hi->name)));
598  vring = vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS(0));
599  tapid->rx_ring_sz = vring->size;
600  vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS(0));
601  tapid->tx_ring_sz = vring->size;
602  clib_memcpy(tapid->host_mac_addr, vif->host_mac_addr, 6);
603  if (vif->host_if_name)
604  {
606  MIN (ARRAY_LEN (tapid->host_if_name) - 1,
607  strlen ((const char *) vif->host_if_name)));
608  }
609  if (vif->net_ns)
610  {
611  clib_memcpy(tapid->host_namespace, vif->net_ns,
612  MIN (ARRAY_LEN (tapid->host_namespace) - 1,
613  strlen ((const char *) vif->net_ns)));
614  }
615  if (vif->host_bridge)
616  {
617  clib_memcpy(tapid->host_bridge, vif->host_bridge,
618  MIN (ARRAY_LEN (tapid->host_bridge) - 1,
619  strlen ((const char *) vif->host_bridge)));
620  }
621  if (vif->host_ip4_prefix_len)
622  clib_memcpy(tapid->host_ip4_addr, &vif->host_ip4_addr, 4);
624  if (vif->host_ip6_prefix_len)
625  clib_memcpy(tapid->host_ip6_addr, &vif->host_ip6_addr, 16);
627  tapid->host_mtu_size = vif->host_mtu_size;
628  );
629  /* *INDENT-ON* */
630 
631  *out_tapids = r_tapids;
632 
633  return 0;
634 }
635 
636 static clib_error_t *
638 {
639  tap_main_t *tm = &tap_main;
640 
642  {
643  if (unformat (input, "host-mtu %d", &tm->host_mtu_size))
644  ;
645  else
646  return clib_error_return (0, "unknown input `%U'",
647  format_unformat_error, input);
648  }
649 
650  return 0;
651 }
652 
653 /* tap { host-mtu <size> } configuration. */
655 
656 static clib_error_t *
658 {
659  tap_main_t *tm = &tap_main;
660  clib_error_t *error = 0;
661 
662  tm->log_default = vlib_log_register_class ("tap", 0);
663  vlib_log_debug (tm->log_default, "initialized");
664 
665  tm->host_mtu_size = 0;
666 
667  return error;
668 }
669 
671 
672 /*
673  * fd.io coding-style-patch-verification: ON
674  *
675  * Local Variables:
676  * eval: (c-set-style "gnu")
677  * End:
678  */
u32 per_interface_next_index
Definition: virtio.h:151
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:398
void virtio_set_net_hdr_size(virtio_if_t *vif)
Definition: virtio.c:263
virtio_if_t * interfaces
Definition: virtio.h:193
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:53
vlib_log_class_t log_default
Definition: tap.h:77
ip4_address_t host_ip4_addr
Definition: virtio.h:178
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:528
vnet_interface_main_t interface_main
Definition: vnet.h:56
vlib_physmem_main_t physmem_main
Definition: main.h:155
int gso_enabled
Definition: virtio.h:183
u32 host_mtu_size
Definition: virtio.h:182
u32 dev_instance
Definition: virtio.h:140
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
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:247
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
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:576
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:224
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:164
u32 hw_if_index
Definition: virtio.h:141
u8 host_mac_addr[6]
Definition: tap.h:63
u8 host_ip6_prefix_len
Definition: virtio.h:181
#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:176
int ifindex
Definition: virtio.h:184
vnet_hw_interface_flags_t flags
Definition: interface.h:506
#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:474
#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:148
u16 num_txqs
Definition: virtio.h:171
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:159
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:170
virtio_vring_t * rxq_vrings
Definition: virtio.h:162
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
vlib_main_t * vm
Definition: buffer.c:323
#define TAP_MAX_INSTANCE
Definition: tap.c:79
static int open_netns_fd(char *netns)
Definition: tap.c:62
#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:180
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:175
u8 mac_addr[6]
Definition: virtio.h:173
u32 flags
Definition: virtio.h:138
#define ARRAY_LEN(x)
Definition: clib.h:63
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:145
#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:164
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:66
u8 * host_if_name
Definition: tap.h:35
u8 host_mac_addr[6]
Definition: virtio.h:177
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:82
#define RX_QUEUE_ACCESS(X)
Definition: virtio.h:81
tap_main_t tap_main
Definition: tap.c:43
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:492
int fd
Definition: virtio.h:154
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:179
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:142
virtio_vring_t * cxq_vring
Definition: virtio.h:185
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:176
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:501
static clib_error_t * tap_mtu_config(vlib_main_t *vm, unformat_input_t *input)
Definition: tap.c:637
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:163
static clib_error_t * tap_init(vlib_main_t *vm)
Definition: tap.c:657
u8 * host_if_name
Definition: virtio.h:174