FD.io VPP  v21.10.1-2-g0a485f517
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 <sys/socket.h>
22 #include <fcntl.h>
23 #include <net/if.h>
24 #include <linux/if_tun.h>
25 #include <sys/ioctl.h>
26 #include <linux/ethtool.h>
27 #include <linux/sockios.h>
28 #include <sys/eventfd.h>
29 #include <net/if_arp.h>
30 #include <limits.h>
31 
32 #include <linux/netlink.h>
33 #include <linux/rtnetlink.h>
34 
35 #include <vlib/vlib.h>
36 #include <vlib/physmem.h>
37 #include <vlib/unix/unix.h>
38 #include <vppinfra/linux/netns.h>
39 #include <vnet/ethernet/ethernet.h>
40 #include <vnet/ip/ip4_packet.h>
41 #include <vnet/ip/ip6_packet.h>
42 #include <vnet/devices/netlink.h>
44 #include <vnet/devices/tap/tap.h>
45 
47 
48 #define tap_log_err(dev, f, ...) \
49  vlib_log (VLIB_LOG_LEVEL_ERR, tap_main.log_default, "tap%u: " f, dev->dev_instance, ## __VA_ARGS__)
50 #define tap_log_dbg(dev, f, ...) \
51  vlib_log (VLIB_LOG_LEVEL_DEBUG, tap_main.log_default, "tap%u: " f, dev->dev_instance, ## __VA_ARGS__)
52 
53 #define _IOCTL(fd,a,...) \
54  if (ioctl (fd, a, __VA_ARGS__) < 0) \
55  { \
56  err = clib_error_return_unix (0, "ioctl(" #a ")"); \
57  tap_log_err (vif, "%U", format_clib_error, err); \
58  goto error; \
59  }
60 
61  /* *INDENT-OFF* */
62 VNET_HW_INTERFACE_CLASS (tun_device_hw_interface_class, static) =
63 {
64  .name = "tun-device",
66 };
67  /* *INDENT-ON* */
68 
69 #define TUN_MAX_PACKET_BYTES 65355
70 #define TUN_MIN_PACKET_BYTES 64
71 #define TUN_DEFAULT_PACKET_BYTES 1500
72 
73 static u32
75  u32 flags)
76 {
77  /* nothing for now */
78  //TODO On MTU change call vnet_netlink_set_if_mtu
79  return 0;
80 }
81 
82 #define TAP_MAX_INSTANCE 1024
83 
84 static void
86 {
88  tap_main_t *tm = &tap_main;
89  clib_error_t *err = 0;
90  int i;
91 
92  /* *INDENT-OFF* */
93  vec_foreach_index (i, vif->vhost_fds) if (vif->vhost_fds[i] != -1)
94  close (vif->vhost_fds[i]);
99  /* *INDENT-ON* */
100 
101  if (vif->tap_fds)
102  {
103  _IOCTL (vif->tap_fds[0], TUNSETPERSIST, (void *) (uintptr_t) 0);
104  tap_log_dbg (vif, "TUNSETPERSIST: unset");
105  }
106 error:
107  vec_foreach_index (i, vif->tap_fds) close (vif->tap_fds[i]);
108 
109  vec_free (vif->vhost_fds);
110  vec_free (vif->rxq_vrings);
111  vec_free (vif->txq_vrings);
112  vec_free (vif->host_if_name);
113  vec_free (vif->net_ns);
114  vec_free (vif->host_bridge);
115  clib_error_free (vif->error);
116 
117  tm->tap_ids = clib_bitmap_set (tm->tap_ids, vif->id, 0);
118  clib_memset (vif, 0, sizeof (*vif));
119  pool_put (mm->interfaces, vif);
120 }
121 
122 void
124 {
127  vnet_main_t *vnm = vnet_get_main ();
128  virtio_main_t *vim = &virtio_main;
129  tap_main_t *tm = &tap_main;
132  int i, num_vhost_queues;
133  int old_netns_fd = -1;
134  struct ifreq ifr = {.ifr_flags = IFF_NO_PI | IFF_VNET_HDR };
135  struct ifreq get_ifr = {.ifr_flags = 0 };
136  size_t hdrsz;
137  vhost_memory_t *vhost_mem = 0;
138  virtio_if_t *vif = 0;
139  clib_error_t *err = 0;
140  unsigned int tap_features;
141  int tfd = -1, qfd = -1, vfd = -1, nfd = -1;
142  char *host_if_name = 0;
143  unsigned int offload = 0;
144  int sndbuf = 0;
145 
146  if (args->id != ~0)
147  {
148  if (clib_bitmap_get (tm->tap_ids, args->id))
149  {
150  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
151  args->error = clib_error_return (0, "interface already exists");
152  return;
153  }
154  }
155  else
156  {
157  args->id = clib_bitmap_first_clear (tm->tap_ids);
158  }
159 
160  if (args->id > TAP_MAX_INSTANCE)
161  {
162  args->rv = VNET_API_ERROR_UNSPECIFIED;
163  args->error = clib_error_return (0, "cannot find free interface id");
164  return;
165  }
166 
167  pool_get_zero (vim->interfaces, vif);
168 
169  if (args->tap_flags & TAP_FLAG_TUN)
170  {
171  vif->type = VIRTIO_IF_TYPE_TUN;
172  ifr.ifr_flags |= IFF_TUN;
173 
174  /*
175  * From kernel 4.20, xdp support has been added in tun_sendmsg.
176  * If sndbuf == INT_MAX, vhost batches the packet and processes
177  * them using xdp data path for tun driver. It assumes packets
178  * are ethernet frames (It needs to be fixed).
179  * To avoid xdp data path in tun driver, sndbuf value should
180  * be < INT_MAX.
181  */
182  sndbuf = INT_MAX - 1;
183  }
184  else
185  {
186  vif->type = VIRTIO_IF_TYPE_TAP;
187  ifr.ifr_flags |= IFF_TAP;
188  sndbuf = INT_MAX;
189  }
190 
191  vif->dev_instance = vif - vim->interfaces;
192  vif->id = args->id;
193  vif->num_txqs = thm->n_vlib_mains;
194  vif->num_rxqs = clib_max (args->num_rx_queues, 1);
195 
196  if (args->tap_flags & TAP_FLAG_ATTACH)
197  {
198  if (args->host_if_name == NULL)
199  {
200  args->rv = VNET_API_ERROR_NO_MATCHING_INTERFACE;
201  err = clib_error_return (0, "host_if_name is not provided");
202  goto error;
203  }
204  if (args->host_namespace)
205  {
206  old_netns_fd = clib_netns_open (NULL /* self */);
207  if ((nfd = clib_netns_open (args->host_namespace)) == -1)
208  {
209  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
210  args->error = clib_error_return_unix (0, "clib_netns_open '%s'",
211  args->host_namespace);
212  goto error;
213  }
214  if (clib_setns (nfd) == -1)
215  {
216  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
217  args->error = clib_error_return_unix (0, "setns '%s'",
218  args->host_namespace);
219  goto error;
220  }
221  }
222  }
223 
224  if (args->host_if_name != NULL)
225  {
226  host_if_name = (char *) args->host_if_name;
227  clib_memcpy (ifr.ifr_name, host_if_name,
228  clib_min (IFNAMSIZ, vec_len (host_if_name)));
229  }
230 
231  if ((tfd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0)
232  {
233  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
234  args->error = clib_error_return_unix (0, "open '/dev/net/tun'");
235  goto error;
236  }
237  vec_add1 (vif->tap_fds, tfd);
238  tap_log_dbg (vif, "open tap fd %d", tfd);
239 
240  _IOCTL (tfd, TUNGETFEATURES, &tap_features);
241  tap_log_dbg (vif, "TUNGETFEATURES: features 0x%lx", tap_features);
242  if ((tap_features & IFF_VNET_HDR) == 0)
243  {
244  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
245  args->error = clib_error_return (0, "vhost-net backend not available");
246  goto error;
247  }
248 
249  if ((tap_features & IFF_MULTI_QUEUE) == 0)
250  {
251  if (vif->num_rxqs > 1)
252  {
253  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
254  args->error = clib_error_return (0, "multiqueue not supported");
255  goto error;
256  }
257  vif->num_rxqs = vif->num_txqs = 1;
258  }
259  else
260  ifr.ifr_flags |= IFF_MULTI_QUEUE;
261 
262  hdrsz = sizeof (virtio_net_hdr_v1_t);
263  if (args->tap_flags & TAP_FLAG_GSO)
264  {
265  offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
266  vif->gso_enabled = 1;
267  }
268  else if (args->tap_flags & TAP_FLAG_CSUM_OFFLOAD)
269  {
270  offload = TUN_F_CSUM;
271  vif->csum_offload_enabled = 1;
272  }
273 
274  _IOCTL (tfd, TUNSETIFF, (void *) &ifr);
275  tap_log_dbg (vif, "TUNSETIFF fd %d name %s flags 0x%x", tfd,
276  ifr.ifr_ifrn.ifrn_name, ifr.ifr_flags);
277 
278  vif->ifindex = if_nametoindex (ifr.ifr_ifrn.ifrn_name);
279  tap_log_dbg (vif, "ifindex %d", vif->ifindex);
280 
281  if (!args->host_if_name)
282  host_if_name = ifr.ifr_ifrn.ifrn_name;
283  else
284  host_if_name = (char *) args->host_if_name;
285 
286  /*
287  * unset the persistence when attaching to existing
288  * interface
289  */
290  if (args->tap_flags & TAP_FLAG_ATTACH)
291  {
292  _IOCTL (tfd, TUNSETPERSIST, (void *) (uintptr_t) 0);
293  tap_log_dbg (vif, "TUNSETPERSIST: unset");
294  }
295 
296  /* set the persistence */
297  if (args->tap_flags & TAP_FLAG_PERSIST)
298  {
299  _IOCTL (tfd, TUNSETPERSIST, (void *) (uintptr_t) 1);
300  tap_log_dbg (vif, "TUNSETPERSIST: set");
301 
302  /* verify persistence is set, read the flags */
303  _IOCTL (tfd, TUNGETIFF, (void *) &get_ifr);
304  tap_log_dbg (vif, "TUNGETIFF: flags 0x%lx", get_ifr.ifr_flags);
305  if ((get_ifr.ifr_flags & IFF_PERSIST) == 0)
306  {
307  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
308  args->error = clib_error_return (0, "persistence not supported");
309  goto error;
310  }
311  }
312 
313  /* create additional queues on the linux side.
314  * we create as many linux queue pairs as we have rx queues
315  */
316  for (i = 1; i < vif->num_rxqs; i++)
317  {
318  if ((qfd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0)
319  {
320  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
321  args->error = clib_error_return_unix (0, "open '/dev/net/tun'");
322  goto error;
323  }
324  _IOCTL (qfd, TUNSETIFF, (void *) &ifr);
325  tap_log_dbg (vif, "TUNSETIFF fd %d name %s flags 0x%x", qfd,
326  ifr.ifr_ifrn.ifrn_name, ifr.ifr_flags);
327  vec_add1 (vif->tap_fds, qfd);
328  }
329 
330  for (i = 0; i < vif->num_rxqs; i++)
331  {
332  tap_log_dbg (vif, "TUNSETVNETHDRSZ: fd %d vnet_hdr_sz %u",
333  vif->tap_fds[i], hdrsz);
334  _IOCTL (vif->tap_fds[i], TUNSETVNETHDRSZ, &hdrsz);
335 
336  tap_log_dbg (vif, "TUNSETSNDBUF: fd %d sndbuf %d", vif->tap_fds[i],
337  sndbuf);
338  _IOCTL (vif->tap_fds[i], TUNSETSNDBUF, &sndbuf);
339 
340  tap_log_dbg (vif, "TUNSETOFFLOAD: fd %d offload 0x%lx", vif->tap_fds[i],
341  offload);
342  _IOCTL (vif->tap_fds[i], TUNSETOFFLOAD, offload);
343 
344  if (fcntl (vif->tap_fds[i], F_SETFL, O_NONBLOCK) < 0)
345  {
346  err = clib_error_return_unix (0, "fcntl(tfd, F_SETFL, O_NONBLOCK)");
347  tap_log_err (vif, "set nonblocking: %U", format_clib_error, err);
348  goto error;
349  }
350  }
351 
352  /* open as many vhost-net fds as required and set ownership */
353  num_vhost_queues = clib_max (vif->num_rxqs, vif->num_txqs);
354  for (i = 0; i < num_vhost_queues; i++)
355  {
356  if ((vfd = open ("/dev/vhost-net", O_RDWR | O_NONBLOCK)) < 0)
357  {
358  args->rv = VNET_API_ERROR_SYSCALL_ERROR_1;
359  args->error = clib_error_return_unix (0, "open '/dev/vhost-net'");
360  goto error;
361  }
362  vec_add1 (vif->vhost_fds, vfd);
363  virtio_log_debug (vif, "open vhost-net fd %d qpair %u", vfd, i);
364  _IOCTL (vfd, VHOST_SET_OWNER, 0);
365  virtio_log_debug (vif, "VHOST_SET_OWNER: fd %u", vfd);
366  }
367 
368  _IOCTL (vif->vhost_fds[0], VHOST_GET_FEATURES, &vif->remote_features);
369  virtio_log_debug (vif, "VHOST_GET_FEATURES: features 0x%lx",
370  vif->remote_features);
371 
372  if ((vif->remote_features & VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF)) == 0)
373  {
374  args->rv = VNET_API_ERROR_UNSUPPORTED;
375  args->error = clib_error_return (0, "vhost-net backend doesn't support "
376  "VIRTIO_NET_F_MRG_RXBUF feature");
377  goto error;
378  }
379 
380  if ((vif->remote_features & VIRTIO_FEATURE (VIRTIO_RING_F_INDIRECT_DESC)) ==
381  0)
382  {
383  args->rv = VNET_API_ERROR_UNSUPPORTED;
384  args->error = clib_error_return (0, "vhost-net backend doesn't support "
385  "VIRTIO_RING_F_INDIRECT_DESC feature");
386  goto error;
387  }
388 
389  if ((vif->remote_features & VIRTIO_FEATURE (VIRTIO_F_VERSION_1)) == 0)
390  {
391  args->rv = VNET_API_ERROR_UNSUPPORTED;
392  args->error = clib_error_return (0, "vhost-net backend doesn't support "
393  "VIRTIO_F_VERSION_1 features");
394  goto error;
395  }
396 
397  vif->features |= VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF);
398  vif->features |= VIRTIO_FEATURE (VIRTIO_F_VERSION_1);
399  vif->features |= VIRTIO_FEATURE (VIRTIO_RING_F_INDIRECT_DESC);
400 
402 
403  if (!(args->tap_flags & TAP_FLAG_ATTACH))
404  {
405  /* if namespace is specified, all further netlink messages should be executed
406  after we change our net namespace */
407  if (args->host_namespace)
408  {
409  old_netns_fd = clib_netns_open (NULL /* self */);
410  if ((nfd = clib_netns_open (args->host_namespace)) == -1)
411  {
412  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
413  args->error = clib_error_return_unix (0, "clib_netns_open '%s'",
414  args->host_namespace);
415  goto error;
416  }
417  args->error = vnet_netlink_set_link_netns (vif->ifindex, nfd,
418  host_if_name);
419  if (args->error)
420  {
421  args->rv = VNET_API_ERROR_NETLINK_ERROR;
422  goto error;
423  }
424  if (clib_setns (nfd) == -1)
425  {
426  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
427  args->error = clib_error_return_unix (0, "setns '%s'",
428  args->host_namespace);
429  goto error;
430  }
431  if ((vif->ifindex = if_nametoindex (host_if_name)) == 0)
432  {
433  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
434  args->error = clib_error_return_unix (0, "if_nametoindex '%s'",
435  host_if_name);
436  goto error;
437  }
438  }
439  }
440 
441  if (vif->type == VIRTIO_IF_TYPE_TAP)
442  {
446  args->host_mac_addr.bytes);
447  if (args->error)
448  {
449  args->rv = VNET_API_ERROR_NETLINK_ERROR;
450  goto error;
451  }
452 
453  if (args->host_bridge)
454  {
456  (char *)
457  args->host_bridge);
458  if (args->error)
459  {
460  args->rv = VNET_API_ERROR_NETLINK_ERROR;
461  goto error;
462  }
463  }
464  }
465 
466  if (args->host_ip4_prefix_len)
467  {
469  &args->host_ip4_addr,
470  args->host_ip4_prefix_len);
471  if (args->error)
472  {
473  args->rv = VNET_API_ERROR_NETLINK_ERROR;
474  goto error;
475  }
476  }
477 
478  if (args->host_ip6_prefix_len)
479  {
481  &args->host_ip6_addr,
482  args->host_ip6_prefix_len);
483  if (args->error)
484  {
485  args->rv = VNET_API_ERROR_NETLINK_ERROR;
486  goto error;
487  }
488  }
489 
490  args->error = vnet_netlink_set_link_state (vif->ifindex, 1 /* UP */ );
491  if (args->error)
492  {
493  args->rv = VNET_API_ERROR_NETLINK_ERROR;
494  goto error;
495  }
496 
497  if (args->host_ip4_gw_set)
498  {
499  args->error = vnet_netlink_add_ip4_route (0, 0, &args->host_ip4_gw);
500  if (args->error)
501  {
502  args->rv = VNET_API_ERROR_NETLINK_ERROR;
503  goto error;
504  }
505  }
506 
507  if (args->host_ip6_gw_set)
508  {
509  args->error = vnet_netlink_add_ip6_route (0, 0, &args->host_ip6_gw);
510  if (args->error)
511  {
512  args->rv = VNET_API_ERROR_NETLINK_ERROR;
513  goto error;
514  }
515  }
516 
517  if (args->host_mtu_set)
518  {
519  args->error =
521  if (args->error)
522  {
523  args->rv = VNET_API_ERROR_NETLINK_ERROR;
524  goto error;
525  }
526  }
527  else if (tm->host_mtu_size != 0)
528  {
529  args->error =
531  if (args->error)
532  {
533  args->rv = VNET_API_ERROR_NETLINK_ERROR;
534  goto error;
535  }
536  args->host_mtu_set = 1;
537  args->host_mtu_size = tm->host_mtu_size;
538  }
539 
540  /* switch back to old net namespace */
541  if (args->host_namespace)
542  {
543  if (clib_setns (old_netns_fd) == -1)
544  {
545  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
546  args->error = clib_error_return_unix (0, "setns '%s'",
547  args->host_namespace);
548  goto error;
549  }
550  }
551 
552  for (i = 0; i < num_vhost_queues; i++)
553  {
554  if (i < vif->num_rxqs && (args->error =
555  virtio_vring_init (vm, vif, RX_QUEUE (i),
556  args->rx_ring_sz)))
557  {
558  args->rv = VNET_API_ERROR_INIT_FAILED;
559  goto error;
560  }
561 
562  if (i < vif->num_txqs && (args->error =
563  virtio_vring_init (vm, vif, TX_QUEUE (i),
564  args->tx_ring_sz)))
565  {
566  args->rv = VNET_API_ERROR_INIT_FAILED;
567  goto error;
568  }
569  }
570 
571  /* setup features and memtable */
572  i = sizeof (vhost_memory_t) + sizeof (vhost_memory_region_t);
573  vhost_mem = clib_mem_alloc (i);
574  clib_memset (vhost_mem, 0, i);
575  vhost_mem->nregions = 1;
576  vhost_mem->regions[0].memory_size = vpm->max_size;
577  vhost_mem->regions[0].guest_phys_addr = vpm->base_addr;
578  vhost_mem->regions[0].userspace_addr =
579  vhost_mem->regions[0].guest_phys_addr;
580 
581  for (i = 0; i < vhost_mem->nregions; i++)
582  virtio_log_debug (vif, "memtable region %u memory_size 0x%lx "
583  "guest_phys_addr 0x%lx userspace_addr 0x%lx", i,
584  vhost_mem->regions[0].memory_size,
585  vhost_mem->regions[0].guest_phys_addr,
586  vhost_mem->regions[0].userspace_addr);
587 
588 
589  for (i = 0; i < num_vhost_queues; i++)
590  {
591  int fd = vif->vhost_fds[i];
592  _IOCTL (fd, VHOST_SET_FEATURES, &vif->features);
593  virtio_log_debug (vif, "VHOST_SET_FEATURES: fd %u features 0x%lx",
594  fd, vif->features);
595  _IOCTL (fd, VHOST_SET_MEM_TABLE, vhost_mem);
596  virtio_log_debug (vif, "VHOST_SET_MEM_TABLE: fd %u", fd);
597  }
598 
599  /* finish initializing queue pair */
600  for (i = 0; i < num_vhost_queues * 2; i++)
601  {
602  vhost_vring_addr_t addr = { 0 };
603  vhost_vring_state_t state = { 0 };
604  vhost_vring_file_t file = { 0 };
605  virtio_vring_t *vring;
606  u16 qp = i >> 1;
607  int fd = vif->vhost_fds[qp];
608 
609  if (i & 1)
610  {
611  if (qp >= vif->num_txqs)
612  continue;
613  vring = vec_elt_at_index (vif->txq_vrings, qp);
614  }
615  else
616  {
617  if (qp >= vif->num_rxqs)
618  continue;
619  vring = vec_elt_at_index (vif->rxq_vrings, qp);
620  }
621 
622  addr.index = state.index = file.index = vring->queue_id & 1;
623  state.num = vring->size;
624  virtio_log_debug (vif, "VHOST_SET_VRING_NUM fd %d index %u num %u", fd,
625  state.index, state.num);
626  _IOCTL (fd, VHOST_SET_VRING_NUM, &state);
627 
628  addr.flags = 0;
632 
633  virtio_log_debug (vif, "VHOST_SET_VRING_ADDR fd %d index %u flags 0x%x "
634  "desc_user_addr 0x%lx avail_user_addr 0x%lx "
635  "used_user_addr 0x%lx", fd, addr.index,
638  _IOCTL (fd, VHOST_SET_VRING_ADDR, &addr);
639 
640  file.fd = vring->call_fd;
641  virtio_log_debug (vif, "VHOST_SET_VRING_CALL fd %d index %u call_fd %d",
642  fd, file.index, file.fd);
643  _IOCTL (fd, VHOST_SET_VRING_CALL, &file);
644 
645  file.fd = vring->kick_fd;
646  virtio_log_debug (vif, "VHOST_SET_VRING_KICK fd %d index %u kick_fd %d",
647  fd, file.index, file.fd);
648  _IOCTL (fd, VHOST_SET_VRING_KICK, &file);
649 
650  file.fd = vif->tap_fds[qp % vif->num_rxqs];
651  virtio_log_debug (vif, "VHOST_NET_SET_BACKEND fd %d index %u tap_fd %d",
652  fd, file.index, file.fd);
653  _IOCTL (fd, VHOST_NET_SET_BACKEND, &file);
654  }
655 
656  if (vif->type == VIRTIO_IF_TYPE_TAP)
657  {
658  if (!args->mac_addr_set)
660 
661  clib_memcpy (vif->mac_addr, args->mac_addr.bytes, 6);
662  vif->host_bridge = format (0, "%s%c", args->host_bridge, 0);
663  }
664  vif->host_if_name = format (0, "%s%c", host_if_name, 0);
665  vif->net_ns = format (0, "%s%c", args->host_namespace, 0);
666  vif->host_mtu_size = args->host_mtu_size;
667  vif->tap_flags = args->tap_flags;
668  clib_memcpy (vif->host_mac_addr, args->host_mac_addr.bytes, 6);
671  if (args->host_ip4_prefix_len)
672  clib_memcpy (&vif->host_ip4_addr, &args->host_ip4_addr, 4);
673  if (args->host_ip6_prefix_len)
674  clib_memcpy (&vif->host_ip6_addr, &args->host_ip6_addr, 16);
675 
676  if (vif->type != VIRTIO_IF_TYPE_TUN)
677  {
678  args->error =
680  vif->dev_instance, vif->mac_addr,
681  &vif->hw_if_index,
683  if (args->error)
684  {
685  args->rv = VNET_API_ERROR_INVALID_REGISTRATION;
686  goto error;
687  }
688 
689  }
690  else
691  {
693  (vnm, virtio_device_class.index,
694  vif->dev_instance /* device instance */ ,
695  tun_device_hw_interface_class.index, vif->dev_instance);
696 
697  }
698  tm->tap_ids = clib_bitmap_set (tm->tap_ids, vif->id, 1);
699  sw = vnet_get_hw_sw_interface (vnm, vif->hw_if_index);
700  vif->sw_if_index = sw->sw_if_index;
701  args->sw_if_index = vif->sw_if_index;
702  args->rv = 0;
703  hw = vnet_get_hw_interface (vnm, vif->hw_if_index);
705  if (args->tap_flags & TAP_FLAG_GSO)
706  {
710  }
711  else if (args->tap_flags & TAP_FLAG_CSUM_OFFLOAD)
712  {
715  }
716  if ((args->tap_flags & TAP_FLAG_GSO)
717  && (args->tap_flags & TAP_FLAG_GRO_COALESCE))
718  {
720  }
721  if (vif->type == VIRTIO_IF_TYPE_TUN)
722  {
726  hw->max_packet_bytes =
729  }
730 
732 
733  vif->per_interface_next_index = ~0;
734  vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP;
737  /*
738  * Host tun/tap driver link carrier state is "up" at creation. The
739  * driver never changes this unless the backend (VPP) changes it using
740  * TUNSETCARRIER ioctl(). See tap_set_carrier().
741  */
742  vif->host_carrier_up = 1;
743 
744  goto done;
745 
746 error:
747  if (err)
748  {
749  ASSERT (args->error == 0);
750  args->error = err;
751  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
752  }
753 
754  tap_log_err (vif, "%U", format_clib_error, args->error);
755  tap_free (vm, vif);
756 done:
757  if (vhost_mem)
758  clib_mem_free (vhost_mem);
759  if (old_netns_fd != -1)
760  close (old_netns_fd);
761  if (nfd != -1)
762  close (nfd);
763 }
764 
765 int
767 {
768  vnet_main_t *vnm = vnet_get_main ();
769  virtio_main_t *mm = &virtio_main;
770  virtio_if_t *vif;
772 
774  if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
775  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
776 
777  vif = pool_elt_at_index (mm->interfaces, hw->dev_instance);
778 
779  if ((vif->type != VIRTIO_IF_TYPE_TAP) && (vif->type != VIRTIO_IF_TYPE_TUN))
780  return VNET_API_ERROR_INVALID_INTERFACE;
781 
782  /* bring down the interface */
785 
786  if (vif->type == VIRTIO_IF_TYPE_TAP)
788  else /* VIRTIO_IF_TYPE_TUN */
790  vif->hw_if_index = ~0;
791 
792  tap_free (vm, vif);
793 
794  return 0;
795 }
796 
797 int
799  int enable_disable)
800 {
801  vnet_main_t *vnm = vnet_get_main ();
802  virtio_main_t *mm = &virtio_main;
803  virtio_if_t *vif;
805  clib_error_t *err = 0;
806  int i = 0;
807 
809 
810  if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
811  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
812 
813  vif = pool_elt_at_index (mm->interfaces, hw->dev_instance);
814 
815  const unsigned int csum_offload_on = TUN_F_CSUM;
816  const unsigned int csum_offload_off = 0;
817  unsigned int offload = enable_disable ? csum_offload_on : csum_offload_off;
818  vec_foreach_index (i, vif->tap_fds)
819  _IOCTL (vif->tap_fds[i], TUNSETOFFLOAD, offload);
820  vif->gso_enabled = 0;
821  vif->packet_coalesce = 0;
822  vif->csum_offload_enabled = enable_disable ? 1 : 0;
823 
825  {
827  }
828 
829  if (enable_disable)
830  {
832  }
833  else
834  {
836  }
837 
838 error:
839  if (err)
840  {
841  clib_warning ("Error %s checksum offload on sw_if_index %d",
842  enable_disable ? "enabling" : "disabling", sw_if_index);
843  return VNET_API_ERROR_SYSCALL_ERROR_3;
844  }
845  return 0;
846 }
847 
848 int
850  int is_packet_coalesce)
851 {
852  vnet_main_t *vnm = vnet_get_main ();
853  virtio_main_t *mm = &virtio_main;
854  virtio_if_t *vif;
856  clib_error_t *err = 0;
857  int i = 0;
858 
860 
861  if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
862  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
863 
864  vif = pool_elt_at_index (mm->interfaces, hw->dev_instance);
865 
866  const unsigned int gso_on = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
867  const unsigned int gso_off = 0;
868  unsigned int offload = enable_disable ? gso_on : gso_off;
869  vec_foreach_index (i, vif->tap_fds)
870  _IOCTL (vif->tap_fds[i], TUNSETOFFLOAD, offload);
871  vif->gso_enabled = enable_disable ? 1 : 0;
872  vif->csum_offload_enabled = 0;
873  if (enable_disable)
874  {
876  {
879  }
880  if (is_packet_coalesce)
881  {
883  }
884  }
885  else
886  {
888  {
891  }
892  vif->packet_coalesce = 0;
893  }
894 
895 error:
896  if (err)
897  {
898  clib_warning ("Error %s gso on sw_if_index %d",
899  enable_disable ? "enabling" : "disabling", sw_if_index);
900  return VNET_API_ERROR_SYSCALL_ERROR_3;
901  }
902  return 0;
903 }
904 
905 int
907 {
908  vnet_main_t *vnm = vnet_get_main ();
909  virtio_main_t *mm = &virtio_main;
910  virtio_if_t *vif;
911  virtio_vring_t *vring;
913  tap_interface_details_t *r_tapids = NULL;
914  tap_interface_details_t *tapid = NULL;
915 
916  /* *INDENT-OFF* */
917  pool_foreach (vif, mm->interfaces) {
918  if ((vif->type != VIRTIO_IF_TYPE_TAP)
919  && (vif->type != VIRTIO_IF_TYPE_TUN))
920  continue;
921  vec_add2(r_tapids, tapid, 1);
922  clib_memset (tapid, 0, sizeof (*tapid));
923  tapid->id = vif->id;
924  tapid->sw_if_index = vif->sw_if_index;
925  hi = vnet_get_hw_interface (vnm, vif->hw_if_index);
926  clib_memcpy(tapid->dev_name, hi->name,
927  MIN (ARRAY_LEN (tapid->dev_name) - 1, vec_len (hi->name)));
928  vring = vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS(0));
929  tapid->rx_ring_sz = vring->size;
930  vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS(0));
931  tapid->tx_ring_sz = vring->size;
932  tapid->tap_flags = vif->tap_flags;
933  clib_memcpy(&tapid->host_mac_addr, vif->host_mac_addr, 6);
934  if (vif->host_if_name)
935  {
937  MIN (ARRAY_LEN (tapid->host_if_name) - 1,
938  vec_len (vif->host_if_name)));
939  }
940  if (vif->net_ns)
941  {
942  clib_memcpy(tapid->host_namespace, vif->net_ns,
943  MIN (ARRAY_LEN (tapid->host_namespace) - 1,
944  vec_len (vif->net_ns)));
945  }
946  if (vif->host_bridge)
947  {
948  clib_memcpy(tapid->host_bridge, vif->host_bridge,
949  MIN (ARRAY_LEN (tapid->host_bridge) - 1,
950  vec_len (vif->host_bridge)));
951  }
952  if (vif->host_ip4_prefix_len)
953  clib_memcpy(tapid->host_ip4_addr.as_u8, &vif->host_ip4_addr, 4);
955  if (vif->host_ip6_prefix_len)
956  clib_memcpy(tapid->host_ip6_addr.as_u8, &vif->host_ip6_addr, 16);
958  tapid->host_mtu_size = vif->host_mtu_size;
959  }
960  /* *INDENT-ON* */
961 
962  *out_tapids = r_tapids;
963 
964  return 0;
965 }
966 
967 /*
968  * Set host tap/tun interface carrier state so it will appear to host
969  * applications that the interface's link state changed.
970  *
971  * If the kernel we're building against does not have support for the
972  * TUNSETCARRIER ioctl command, do nothing.
973  */
974 int
975 tap_set_carrier (u32 hw_if_index, u32 carrier_up)
976 {
977  int ret = 0;
978 #ifdef TUNSETCARRIER
979  vnet_main_t *vnm = vnet_get_main ();
980  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
981  virtio_main_t *mm = &virtio_main;
982  virtio_if_t *vif;
983  int *fd;
984 
985  vif = pool_elt_at_index (mm->interfaces, hi->dev_instance);
986  vec_foreach (fd, vif->tap_fds)
987  {
988  ret = ioctl (*fd, TUNSETCARRIER, &carrier_up);
989  if (ret < 0)
990  {
991  clib_warning ("ioctl (TUNSETCARRIER) returned %d", ret);
992  break;
993  }
994  }
995  if (!ret)
996  vif->host_carrier_up = (carrier_up != 0);
997 #endif
998 
999  return ret;
1000 }
1001 
1002 static clib_error_t *
1004 {
1005  tap_main_t *tm = &tap_main;
1006 
1007  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1008  {
1009  if (unformat (input, "host-mtu %d", &tm->host_mtu_size))
1010  ;
1011  else
1012  return clib_error_return (0, "unknown input `%U'",
1013  format_unformat_error, input);
1014  }
1015 
1016  return 0;
1017 }
1018 
1019 /*
1020  * Set host tap/tun interface speed in Mbps.
1021  */
1022 int
1023 tap_set_speed (u32 hw_if_index, u32 speed)
1024 {
1025  vnet_main_t *vnm = vnet_get_main ();
1026  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1027  virtio_main_t *mm = &virtio_main;
1028  virtio_if_t *vif;
1029  int old_netns_fd = -1;
1030  int nfd = -1;
1031  int ctl_fd = -1;
1032  struct ifreq ifr;
1033  struct ethtool_cmd ecmd;
1034  int ret = -1;
1035 
1036  vif = pool_elt_at_index (mm->interfaces, hi->dev_instance);
1037 
1038  if (vif->net_ns)
1039  {
1040  old_netns_fd = clib_netns_open (NULL /* self */);
1041  if ((nfd = clib_netns_open (vif->net_ns)) == -1)
1042  {
1043  clib_warning ("Cannot open netns");
1044  goto done;
1045  }
1046  if (clib_setns (nfd) == -1)
1047  {
1048  clib_warning ("Cannot set ns");
1049  goto done;
1050  }
1051  }
1052 
1053  if ((ctl_fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
1054  {
1055  clib_warning ("Cannot open control socket");
1056  goto done;
1057  }
1058 
1059  ecmd.cmd = ETHTOOL_GSET;
1060  clib_memset (&ifr, 0, sizeof (ifr));
1061  clib_memcpy (ifr.ifr_name, vif->host_if_name,
1062  strlen ((const char *) vif->host_if_name));
1063  ifr.ifr_data = (void *) &ecmd;
1064  if ((ret = ioctl (ctl_fd, SIOCETHTOOL, &ifr)) < 0)
1065  {
1066  clib_warning ("Cannot get device settings");
1067  goto done;
1068  }
1069 
1070  if (ethtool_cmd_speed (&ecmd) != speed)
1071  {
1072  ecmd.cmd = ETHTOOL_SSET;
1073  ethtool_cmd_speed_set (&ecmd, speed);
1074  if ((ret = ioctl (ctl_fd, SIOCETHTOOL, &ifr)) < 0)
1075  {
1076  clib_warning ("Cannot set device settings");
1077  goto done;
1078  }
1079  }
1080 
1081 done:
1082  if (old_netns_fd != -1)
1083  {
1084  if (clib_setns (old_netns_fd) == -1)
1085  {
1086  clib_warning ("Cannot set old ns");
1087  }
1088  close (old_netns_fd);
1089  }
1090  if (nfd != -1)
1091  close (nfd);
1092  if (ctl_fd != -1)
1093  close (ctl_fd);
1094 
1095  return ret;
1096 }
1097 
1098 /* tap { host-mtu <size> } configuration. */
1100 
1101 static clib_error_t *
1103 {
1104  tap_main_t *tm = &tap_main;
1105  clib_error_t *error = 0;
1106 
1107  tm->log_default = vlib_log_register_class ("tap", 0);
1108  vlib_log_debug (tm->log_default, "initialized");
1109 
1110  tm->host_mtu_size = 0;
1111 
1112  return error;
1113 }
1114 
1116 
1117 /*
1118  * fd.io coding-style-patch-verification: ON
1119  *
1120  * Local Variables:
1121  * eval: (c-set-style "gnu")
1122  * End:
1123  */
tap_interface_details_t::host_ip6_prefix_len
u8 host_ip6_prefix_len
Definition: tap.h:87
tap_interface_details_t::host_ip6_addr
ip6_address_t host_ip6_addr
Definition: tap.h:86
vlib_physmem_main_t::max_size
uword max_size
Definition: physmem.h:60
vlib.h
virtio_device_class
vnet_device_class_t virtio_device_class
vnet_hw_interface_t::min_packet_bytes
u32 min_packet_bytes
Definition: interface.h:697
virtio_if_t::host_ip4_prefix_len
u8 host_ip4_prefix_len
Definition: virtio.h:188
tap_create_if_args_t::host_ip4_gw
ip4_address_t host_ip4_gw
Definition: tap.h:57
VHOST_SET_VRING_KICK
#define VHOST_SET_VRING_KICK
Definition: vhost_std.h:74
tap_create_if_args_t::error
clib_error_t * error
Definition: tap.h:68
virtio_if_t::ifindex
int ifindex
Definition: virtio.h:186
virtio_vring_free_rx
clib_error_t * virtio_vring_free_rx(vlib_main_t *vm, virtio_if_t *vif, u32 idx)
Definition: virtio.c:143
vnet_sw_interface_set_flags
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:523
tap_init
static clib_error_t * tap_init(vlib_main_t *vm)
Definition: tap.c:1102
tap_mtu_config
static clib_error_t * tap_mtu_config(vlib_main_t *vm, unformat_input_t *input)
Definition: tap.c:1003
vhost_memory_region_t::memory_size
u64 memory_size
Definition: vhost_std.h:21
vnet_sw_interface_set_mtu
void vnet_sw_interface_set_mtu(vnet_main_t *vnm, u32 sw_if_index, u32 mtu)
Definition: interface.c:706
vnet_sw_interface_t
Definition: interface.h:869
tap_gso_enable_disable
int tap_gso_enable_disable(vlib_main_t *vm, u32 sw_if_index, int enable_disable, int is_packet_coalesce)
Definition: tap.c:849
virtio_vring_t::call_fd
int call_fd
Definition: virtio.h:95
tap_create_if_args_t::host_ip4_addr
ip4_address_t host_ip4_addr
Definition: tap.h:55
VNET_HW_INTERFACE_CAP_SUPPORTS_L4_TX_CKSUM
#define VNET_HW_INTERFACE_CAP_SUPPORTS_L4_TX_CKSUM
Definition: interface.h:555
virtio_vring_free_tx
clib_error_t * virtio_vring_free_tx(vlib_main_t *vm, virtio_if_t *vif, u32 idx)
Definition: virtio.c:165
vnet_hw_interface_t::caps
vnet_hw_interface_capabilities_t caps
Definition: interface.h:645
vhost_vring_addr_t::avail_user_addr
u64 avail_user_addr
Definition: vhost_std.h:51
TX_QUEUE_ACCESS
#define TX_QUEUE_ACCESS(X)
Definition: virtio.h:39
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
virtio_vring_t
Definition: virtio.h:63
virtio.h
clib_max
#define clib_max(x, y)
Definition: clib.h:335
tap_create_if
void tap_create_if(vlib_main_t *vm, tap_create_if_args_t *args)
Definition: tap.c:123
pointer_to_uword
static uword pointer_to_uword(const void *p)
Definition: types.h:131
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:549
tap_main
tap_main_t tap_main
Definition: tap.c:46
tap_create_if_args_t::num_rx_queues
u8 num_rx_queues
Definition: tap.h:47
virtio_if_t::mac_addr
u8 mac_addr[6]
Definition: virtio.h:171
virtio_if_t::flags
u32 flags
Definition: virtio.h:132
virtio_if_t::error
clib_error_t * error
Definition: virtio.h:163
vnet_hw_interface_t::sw_if_index
u32 sw_if_index
Definition: interface.h:670
VHOST_SET_VRING_ADDR
#define VHOST_SET_VRING_ADDR
Definition: vhost_std.h:71
vlib_log_register_class
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:339
clib_mem_free
static void clib_mem_free(void *p)
Definition: mem.h:314
vhost_vring_addr_t::desc_user_addr
u64 desc_user_addr
Definition: vhost_std.h:49
TUN_MIN_PACKET_BYTES
#define TUN_MIN_PACKET_BYTES
Definition: tap.c:70
vlib_physmem_main_t::base_addr
uword base_addr
Definition: physmem.h:59
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
tap_create_if_args_t::mac_addr
mac_address_t mac_addr
Definition: tap.h:46
tap_create_if_args_t::tx_ring_sz
u16 tx_ring_sz
Definition: tap.h:49
RX_QUEUE
#define RX_QUEUE(X)
Definition: virtio.h:38
virtio_if_t::host_carrier_up
u8 host_carrier_up
Definition: virtio.h:190
vnet_hw_interface_t::max_packet_bytes
u32 max_packet_bytes
Definition: interface.h:700
if_nametoindex
unsigned int if_nametoindex(const char *ifname)
vhost_memory_t::nregions
u32 nregions
Definition: vhost_std.h:28
virtio_if_t::per_interface_next_index
u32 per_interface_next_index
Definition: virtio.h:133
virtio_vring_t::kick_fd
int kick_fd
Definition: virtio.h:94
u16
unsigned short u16
Definition: types.h:57
vhost_memory_region_t::guest_phys_addr
u64 guest_phys_addr
Definition: vhost_std.h:20
tap_interface_details_t::sw_if_index
u32 sw_if_index
Definition: tap.h:75
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
VNET_HW_INTERFACE_CLASS
VNET_HW_INTERFACE_CLASS(tun_device_hw_interface_class, static)
ethernet_mac_address_is_zero
static int ethernet_mac_address_is_zero(const u8 *mac)
Definition: mac_address.h:68
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
tap_create_if_args_t
Definition: tap.h:42
VNET_HW_INTERFACE_FLAG_LINK_UP
@ VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:509
VIRTIO_FEATURE
#define VIRTIO_FEATURE(X)
Definition: virtio_std.h:67
state
vl_api_dhcp_client_state_t state
Definition: dhcp.api:201
virtio_vring_t::queue_id
u16 queue_id
Definition: virtio.h:84
virtio_if_t::packet_coalesce
int packet_coalesce
Definition: virtio.h:156
hi
vl_api_ip4_address_t hi
Definition: arp.api:37
VHOST_SET_OWNER
#define VHOST_SET_OWNER
Definition: vhost_std.h:65
unformat_input_t
struct _unformat_input_t unformat_input_t
vnet_hw_interface_t::dev_instance
u32 dev_instance
Definition: interface.h:660
addr
vhost_vring_addr_t addr
Definition: vhost_user.h:130
tap_create_if_args_t::host_ip6_gw
ip6_address_t host_ip6_gw
Definition: tap.h:61
virtio_vring_t::size
u16 size
Definition: virtio.h:83
clib_netns_open
__clib_export int clib_netns_open(u8 *netns_u8)
Definition: netns.c:23
clib_bitmap_first_clear
static uword clib_bitmap_first_clear(uword *ai)
Return the lowest numbered clear bit in a bitmap.
Definition: bitmap.h:432
virtio_vring_init
clib_error_t * virtio_vring_init(vlib_main_t *vm, virtio_if_t *vif, u16 idx, u16 sz)
Definition: virtio.c:60
ethernet.h
virtio_vring_t::avail
vring_avail_t * avail
Definition: virtio.h:73
error
Definition: cJSON.c:88
tap_interface_details_t::host_mac_addr
mac_address_t host_mac_addr
Definition: tap.h:80
tap_create_if_args_t::host_mtu_size
u32 host_mtu_size
Definition: tap.h:64
format_clib_error
__clib_export u8 * format_clib_error(u8 *s, va_list *va)
Definition: error.c:191
virtio_if_t::num_rxqs
u16 num_rxqs
Definition: virtio.h:134
virtio_if_t::host_mac_addr
u8 host_mac_addr[6]
Definition: virtio.h:182
ip6_packet.h
virtio_if_t::vhost_fds
int * vhost_fds
Definition: virtio.h:178
VHOST_SET_VRING_NUM
#define VHOST_SET_VRING_NUM
Definition: vhost_std.h:70
VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM
@ VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM
Definition: interface.h:524
VLIB_CONFIG_FUNCTION
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:181
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
tap_create_if_args_t::host_ip4_prefix_len
u8 host_ip4_prefix_len
Definition: tap.h:56
vhost_vring_addr_t::flags
u32 flags
Definition: vhost_std.h:48
tap_create_if_args_t::host_ip6_addr
ip6_address_t host_ip6_addr
Definition: tap.h:59
vnet_sw_interface_t::sw_if_index
u32 sw_if_index
Definition: interface.h:876
virtio_main
virtio_main_t virtio_main
Definition: virtio.c:37
vhost_vring_state_t
Definition: vhost_std.h:33
virtio_set_packet_coalesce
void virtio_set_packet_coalesce(virtio_if_t *vif)
Definition: virtio.c:188
vlib_thread_main_t::n_vlib_mains
u32 n_vlib_mains
Definition: threads.h:262
pool_foreach
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
tap_csum_offload_enable_disable
int tap_csum_offload_enable_disable(vlib_main_t *vm, u32 sw_if_index, int enable_disable)
Definition: tap.c:798
tap_interface_details_t::host_namespace
u8 host_namespace[64]
Definition: tap.h:82
virtio_if_t::host_ip4_addr
ip4_address_t host_ip4_addr
Definition: virtio.h:187
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
tap_create_if_args_t::host_namespace
u8 * host_namespace
Definition: tap.h:51
tap_interface_details_t::id
u32 id
Definition: tap.h:74
vhost_memory_region_t::userspace_addr
u64 userspace_addr
Definition: vhost_std.h:22
tap_interface_details_t::dev_name
u8 dev_name[64]
Definition: tap.h:77
virtio_if_t::txq_vrings
virtio_vring_t * txq_vrings
Definition: virtio.h:137
clib_bitmap_get
static uword clib_bitmap_get(uword *ai, uword i)
Gets the ith bit value from a bitmap.
Definition: bitmap.h:197
virtio_vring_t::used
vring_used_t * used
Definition: virtio.h:72
vlib_main_t::physmem_main
vlib_physmem_main_t physmem_main
Definition: main.h:170
vec_add2
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:644
tap_create_if_args_t::host_ip4_gw_set
u8 host_ip4_gw_set
Definition: tap.h:58
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
virtio_if_t::host_ip6_addr
ip6_address_t host_ip6_addr
Definition: virtio.h:177
virtio_if_t::net_ns
u8 * net_ns
Definition: virtio.h:180
VHOST_SET_VRING_CALL
#define VHOST_SET_VRING_CALL
Definition: vhost_std.h:75
virtio_vring_t::desc
vring_desc_t * desc
Definition: virtio.h:71
vec_elt_at_index
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Definition: vec_bootstrap.h:203
vnet_get_hw_interface
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface_funcs.h:44
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO
@ VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO
Definition: interface.h:537
tap_main_t::log_default
vlib_log_class_t log_default
Definition: tap.h:94
virtio_if_t::features
u64 features
Definition: virtio.h:131
MIN
#define MIN(x, y)
Definition: node.h:31
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
tap_interface_details_t::host_bridge
u8 host_bridge[64]
Definition: tap.h:83
tap_main_t::host_mtu_size
int host_mtu_size
Definition: tap.h:100
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
tap_log_dbg
#define tap_log_dbg(dev, f,...)
Definition: tap.c:50
vlib_config_function_runtime_t
Definition: init.h:68
VHOST_SET_MEM_TABLE
#define VHOST_SET_MEM_TABLE
Definition: vhost_std.h:67
vnet_get_sup_hw_interface_api_visible_or_null
static vnet_hw_interface_t * vnet_get_sup_hw_interface_api_visible_or_null(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:101
virtio_if_t::csum_offload_enabled
int csum_offload_enabled
Definition: virtio.h:139
vec_foreach_index
#define vec_foreach_index(var, v)
Iterate over vector indices.
Definition: vec_bootstrap.h:220
tap_create_if_args_t::mac_addr_set
u8 mac_addr_set
Definition: tap.h:45
vnet_delete_hw_interface
void vnet_delete_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:1051
tap_interface_details_t::host_ip4_prefix_len
u8 host_ip4_prefix_len
Definition: tap.h:85
if
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
VHOST_SET_FEATURES
#define VHOST_SET_FEATURES
Definition: vhost_std.h:64
vnet_hw_interface_t::dev_class_index
u32 dev_class_index
Definition: interface.h:659
tap_main_t
Definition: tap.h:91
vhost_vring_file_t::fd
int fd
Definition: vhost_std.h:42
virtio_if_t::hw_if_index
u32 hw_if_index
Definition: virtio.h:152
tap_interface_details_t::host_ip4_addr
ip4_address_t host_ip4_addr
Definition: tap.h:84
tap_delete_if
int tap_delete_if(vlib_main_t *vm, u32 sw_if_index)
Definition: tap.c:766
tap_create_if_args_t::id
u32 id
Definition: tap.h:44
virtio_set_net_hdr_size
void virtio_set_net_hdr_size(virtio_if_t *vif)
Definition: virtio.c:288
clib_setns
__clib_export int clib_setns(int nfd)
Definition: netns.c:44
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
tap.h
vlib_log_debug
#define vlib_log_debug(...)
Definition: log.h:137
virtio_if_t::host_if_name
u8 * host_if_name
Definition: virtio.h:179
mac_address_t_::bytes
u8 bytes[6]
Definition: mac_address.h:25
VHOST_NET_SET_BACKEND
#define VHOST_NET_SET_BACKEND
Definition: vhost_std.h:77
clib_bitmap_set
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_min
#define clib_min(x, y)
Definition: clib.h:342
vnet_hw_interface_t::max_supported_packet_bytes
u32 max_supported_packet_bytes
Definition: interface.h:694
VHOST_GET_FEATURES
#define VHOST_GET_FEATURES
Definition: vhost_std.h:63
virtio_if_t::sw_if_index
u32 sw_if_index
Definition: virtio.h:153
vhost_vring_addr_t::used_user_addr
u64 used_user_addr
Definition: vhost_std.h:50
tap_create_if_args_t::host_ip6_prefix_len
u8 host_ip6_prefix_len
Definition: tap.h:60
ip4_packet.h
tap_create_if_args_t::rx_ring_sz
u16 rx_ring_sz
Definition: tap.h:48
virtio_main_t
Definition: virtio.h:214
ip4_address_t::as_u8
u8 as_u8[4]
Definition: ip4_packet.h:55
vnet_hw_interface_t
Definition: interface.h:638
vnet_main_t
Definition: vnet.h:76
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
virtio_if_t::dev_instance
u32 dev_instance
Definition: virtio.h:158
ethernet_mac_address_generate
static void ethernet_mac_address_generate(u8 *mac)
Definition: mac_address.h:74
virtio_log_debug
#define virtio_log_debug(vif, f,...)
Definition: virtio.h:273
TX_QUEUE
#define TX_QUEUE(X)
Definition: virtio.h:37
RX_QUEUE_ACCESS
#define RX_QUEUE_ACCESS(X)
Definition: virtio.h:40
vhost_vring_addr_t::index
u32 index
Definition: vhost_std.h:47
virtio_if_t::num_txqs
u16 num_txqs
Definition: virtio.h:135
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
vhost_vring_file_t::index
u32 index
Definition: vhost_std.h:41
vnet_get_hw_sw_interface
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface_funcs.h:72
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
ethernet_delete_interface
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:393
tap_interface_details_t
TAP interface details struct.
Definition: tap.h:72
vnet_hw_interface_t::min_supported_packet_bytes
u32 min_supported_packet_bytes
Definition: interface.h:691
vlib_thread_main_t
Definition: threads.h:243
virtio_if_t::remote_features
u64 remote_features
Definition: virtio.h:160
tap_set_carrier
int tap_set_carrier(u32 hw_if_index, u32 carrier_up)
Definition: tap.c:975
tap_free
static void tap_free(vlib_main_t *vm, virtio_if_t *vif)
Definition: tap.c:85
virtio_if_t::tap_fds
int * tap_fds
Definition: virtio.h:142
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
tap_create_if_args_t::host_bridge
u8 * host_bridge
Definition: tap.h:54
clib_error_return_unix
#define clib_error_return_unix(e, args...)
Definition: error.h:102
virtio_if_t::type
virtio_if_type_t type
Definition: virtio.h:150
virtio_if_t
Definition: virtio.h:128
tap_log_err
#define tap_log_err(dev, f,...)
Definition: tap.c:48
tap_interface_details_t::tx_ring_sz
u16 tx_ring_sz
Definition: tap.h:78
virtio_if_t::tap_flags
u32 tap_flags
Definition: virtio.h:185
virtio_if_t::rxq_vrings
virtio_vring_t * rxq_vrings
Definition: virtio.h:136
tap_main_t::tap_ids
uword * tap_ids
Definition: tap.h:97
virtio_main_t::interfaces
virtio_if_t * interfaces
Definition: virtio.h:220
physmem.h
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
virtio_if_t::host_bridge
u8 * host_bridge
Definition: virtio.h:181
vhost_memory_t
Definition: vhost_std.h:26
tap_create_if_args_t::host_ip6_gw_set
u8 host_ip6_gw_set
Definition: tap.h:62
pool_get_zero
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:258
clib_error_t
Definition: clib_error.h:21
vnet_hw_interface_set_flags
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:513
unix.h
TAP_MAX_INSTANCE
#define TAP_MAX_INSTANCE
Definition: tap.c:82
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
tap_create_if_args_t::host_if_name
u8 * host_if_name
Definition: tap.h:52
i
int i
Definition: flowhash_template.h:376
VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM
@ VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM
Definition: interface.h:525
VNET_HW_INTERFACE_CLASS_FLAG_P2P
@ VNET_HW_INTERFACE_CLASS_FLAG_P2P
a point 2 point interface
Definition: interface.h:394
vlib_physmem_main_t
Definition: physmem.h:56
clib_warning
#define clib_warning(format, args...)
Definition: error.h:59
VNET_HW_INTERFACE_CAP_SUPPORTS_INT_MODE
@ VNET_HW_INTERFACE_CAP_SUPPORTS_INT_MODE
Definition: interface.h:550
clib_error_free
#define clib_error_free(e)
Definition: error.h:86
tap_create_if_args_t::tap_flags
u32 tap_flags
Definition: tap.h:50
tap_interface_details_t::host_mtu_size
u32 host_mtu_size
Definition: tap.h:88
virtio_if_t::host_ip6_prefix_len
u8 host_ip6_prefix_len
Definition: virtio.h:189
tap_interface_details_t::tap_flags
u32 tap_flags
Definition: tap.h:76
virtio_eth_flag_change
static u32 virtio_eth_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
Definition: tap.c:74
tap_dump_ifs
int tap_dump_ifs(tap_interface_details_t **out_tapids)
Definition: tap.c:906
virtio_vring_set_rx_queues
void virtio_vring_set_rx_queues(vlib_main_t *vm, virtio_if_t *vif)
Definition: virtio.c:238
tap_create_if_args_t::host_mtu_set
u8 host_mtu_set
Definition: tap.h:63
tap_create_if_args_t::sw_if_index
u32 sw_if_index
Definition: tap.h:66
vlib_get_thread_main
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
TUN_DEFAULT_PACKET_BYTES
#define TUN_DEFAULT_PACKET_BYTES
Definition: tap.c:71
tap_interface_details_t::host_if_name
u8 host_if_name[64]
Definition: tap.h:81
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
vhost_memory_region_t
Definition: vhost_std.h:18
vhost_vring_addr_t
Definition: vhost_std.h:45
vhost_vring_file_t
Definition: vhost_std.h:39
virtio_if_t::host_mtu_size
u32 host_mtu_size
Definition: virtio.h:184
vhost_memory_t::regions
vhost_memory_region_t regions[0]
Definition: vhost_std.h:30
clib_mem_alloc
static void * clib_mem_alloc(uword size)
Definition: mem.h:256
tap_interface_details_t::rx_ring_sz
u16 rx_ring_sz
Definition: tap.h:79
vnet_register_interface
u32 vnet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u32 hw_class_index, u32 hw_instance)
Definition: interface.c:812
ethernet_register_interface
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:348
tap_create_if_args_t::host_mac_addr
mac_address_t host_mac_addr
Definition: tap.h:53
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
virtio_if_t::gso_enabled
int gso_enabled
Definition: virtio.h:138
tap_create_if_args_t::rv
int rv
Definition: tap.h:67
tap_set_speed
int tap_set_speed(u32 hw_if_index, u32 speed)
Definition: tap.c:1023
TUN_MAX_PACKET_BYTES
#define TUN_MAX_PACKET_BYTES
Definition: tap.c:69
virtio_if_t::id
u32 id
Definition: virtio.h:183
netns.h
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105