FD.io VPP  v18.11-rc0-18-g2a3fb1a
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 ();
85  virtio_main_t *vim = &virtio_main;
86  tap_main_t *tm = &tap_main;
89  int i;
90  int old_netns_fd = -1;
91  struct ifreq ifr;
92  size_t hdrsz;
93  struct vhost_memory *vhost_mem = 0;
94  virtio_if_t *vif = 0;
95  clib_error_t *err = 0;
96 
97  if (args->id != ~0)
98  {
99  if (clib_bitmap_get (tm->tap_ids, args->id))
100  {
101  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
102  args->error = clib_error_return (0, "interface already exists");
103  return;
104  }
105  }
106  else
107  {
108  args->id = clib_bitmap_first_clear (tm->tap_ids);
109  }
110 
111  if (args->id > TAP_MAX_INSTANCE)
112  {
113  args->rv = VNET_API_ERROR_UNSPECIFIED;
114  args->error = clib_error_return (0, "cannot find free interface id");
115  return;
116  }
117 
118  memset (&ifr, 0, sizeof (ifr));
119  pool_get (vim->interfaces, vif);
120  vif->dev_instance = vif - vim->interfaces;
121  vif->tap_fd = -1;
122  vif->id = args->id;
123 
124  if ((vif->fd = open ("/dev/vhost-net", O_RDWR | O_NONBLOCK)) < 0)
125  {
126  args->rv = VNET_API_ERROR_SYSCALL_ERROR_1;
127  args->error = clib_error_return_unix (0, "open '/dev/vhost-net'");
128  goto error;
129  }
130 
131  _IOCTL (vif->fd, VHOST_GET_FEATURES, &vif->remote_features);
132 
133  if ((vif->remote_features & (1ULL << VIRTIO_NET_F_MRG_RXBUF)) == 0)
134  {
135  args->rv = VNET_API_ERROR_UNSUPPORTED;
136  args->error = clib_error_return (0, "vhost-net backend doesn't support "
137  "VIRTIO_NET_F_MRG_RXBUF feature");
138  goto error;
139  }
140 
141  if ((vif->remote_features & (1ULL << VIRTIO_RING_F_INDIRECT_DESC)) == 0)
142  {
143  args->rv = VNET_API_ERROR_UNSUPPORTED;
144  args->error = clib_error_return (0, "vhost-net backend doesn't support "
145  "VIRTIO_RING_F_INDIRECT_DESC feature");
146  goto error;
147  }
148 
149  if ((vif->remote_features & (1ULL << VIRTIO_F_VERSION_1)) == 0)
150  {
151  args->rv = VNET_API_ERROR_UNSUPPORTED;
152  args->error = clib_error_return (0, "vhost-net backend doesn't support "
153  "VIRTIO_F_VERSION_1 features");
154  goto error;
155  }
156 
157  vif->features |= 1ULL << VIRTIO_NET_F_MRG_RXBUF;
158  vif->features |= 1ULL << VIRTIO_F_VERSION_1;
159  vif->features |= 1ULL << VIRTIO_RING_F_INDIRECT_DESC;
160 
161  _IOCTL (vif->fd, VHOST_SET_FEATURES, &vif->features);
162 
163  if ((vif->tap_fd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0)
164  {
165  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
166  args->error = clib_error_return_unix (0, "open '/dev/net/tun'");
167  goto error;
168  }
169 
170  ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR;
171  _IOCTL (vif->tap_fd, TUNSETIFF, (void *) &ifr);
172  vif->ifindex = if_nametoindex (ifr.ifr_ifrn.ifrn_name);
173 
174  unsigned int offload = 0;
175  hdrsz = sizeof (struct virtio_net_hdr_v1);
176  _IOCTL (vif->tap_fd, TUNSETOFFLOAD, offload);
177  _IOCTL (vif->tap_fd, TUNSETVNETHDRSZ, &hdrsz);
178  _IOCTL (vif->fd, VHOST_SET_OWNER, 0);
179 
180  /* if namespace is specified, all further netlink messages should be excuted
181  after we change our net namespace */
182  if (args->host_namespace)
183  {
184  int fd;
185  old_netns_fd = open ("/proc/self/ns/net", O_RDONLY);
186  if ((fd = open_netns_fd ((char *) args->host_namespace)) == -1)
187  {
188  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
189  args->error = clib_error_return_unix (0, "open_netns_fd '%s'",
190  args->host_namespace);
191  goto error;
192  }
193  args->error = vnet_netlink_set_link_netns (vif->ifindex, fd,
194  (char *) args->host_if_name);
195  if (args->error)
196  {
197  args->rv = VNET_API_ERROR_NETLINK_ERROR;
198  goto error;
199  }
200  if (setns (fd, CLONE_NEWNET) == -1)
201  {
202  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
203  args->error = clib_error_return_unix (0, "setns '%s'",
204  args->host_namespace);
205  goto error;
206  }
207  close (fd);
208  if ((vif->ifindex = if_nametoindex ((char *) args->host_if_name)) == 0)
209  {
210  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
211  args->error = clib_error_return_unix (0, "if_nametoindex '%s'",
212  args->host_if_name);
213  goto error;
214  }
215  }
216  else
217  {
218  if (args->host_if_name)
219  {
221  (char *)
222  args->host_if_name);
223  if (args->error)
224  {
225  args->rv = VNET_API_ERROR_NETLINK_ERROR;
226  goto error;
227  }
228  }
229  }
230 
232  {
234  args->host_mac_addr);
235  if (args->error)
236  {
237  args->rv = VNET_API_ERROR_NETLINK_ERROR;
238  goto error;
239  }
240  }
241 
242  if (args->host_bridge)
243  {
245  (char *) args->host_bridge);
246  if (args->error)
247  {
248  args->rv = VNET_API_ERROR_NETLINK_ERROR;
249  goto error;
250  }
251  }
252 
253 
254  if (args->host_ip4_prefix_len)
255  {
257  &args->host_ip4_addr,
258  args->host_ip4_prefix_len);
259  if (args->error)
260  {
261  args->rv = VNET_API_ERROR_NETLINK_ERROR;
262  goto error;
263  }
264  }
265 
266  if (args->host_ip6_prefix_len)
267  {
269  &args->host_ip6_addr,
270  args->host_ip6_prefix_len);
271  if (args->error)
272  {
273  args->rv = VNET_API_ERROR_NETLINK_ERROR;
274  goto error;
275  }
276  }
277 
278  args->error = vnet_netlink_set_link_state (vif->ifindex, 1 /* UP */ );
279  if (args->error)
280  {
281  args->rv = VNET_API_ERROR_NETLINK_ERROR;
282  goto error;
283  }
284 
285  if (args->host_ip4_gw_set)
286  {
287  args->error = vnet_netlink_add_ip4_route (0, 0, &args->host_ip4_gw);
288  if (args->error)
289  {
290  args->rv = VNET_API_ERROR_NETLINK_ERROR;
291  goto error;
292  }
293  }
294 
295  if (args->host_ip6_gw_set)
296  {
297  args->error = vnet_netlink_add_ip6_route (0, 0, &args->host_ip6_gw);
298  if (args->error)
299  {
300  args->rv = VNET_API_ERROR_NETLINK_ERROR;
301  goto error;
302  }
303  }
304 
305  /* switch back to old net namespace */
306  if (args->host_namespace)
307  {
308  if (setns (old_netns_fd, CLONE_NEWNET) == -1)
309  {
310  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
311  args->error = clib_error_return_unix (0, "setns '%s'",
312  args->host_namespace);
313  goto error;
314  }
315  }
316 
317  /* Set vhost memory table */
318  i = sizeof (struct vhost_memory) + sizeof (struct vhost_memory_region);
319  vhost_mem = clib_mem_alloc (i);
320  memset (vhost_mem, 0, i);
321  vhost_mem->nregions = 1;
322  vhost_mem->regions[0].memory_size = (1ULL << 47) - 4096;
323  _IOCTL (vif->fd, VHOST_SET_MEM_TABLE, vhost_mem);
324 
325  if ((args->error = virtio_vring_init (vm, vif, 0, args->rx_ring_sz)))
326  {
327  args->rv = VNET_API_ERROR_INIT_FAILED;
328  goto error;
329  }
330 
331  if ((args->error = virtio_vring_init (vm, vif, 1, args->tx_ring_sz)))
332  {
333  args->rv = VNET_API_ERROR_INIT_FAILED;
334  goto error;
335  }
336 
337  if (!args->mac_addr_set)
338  {
339  f64 now = vlib_time_now (vm);
340  u32 rnd;
341  rnd = (u32) (now * 1e6);
342  rnd = random_u32 (&rnd);
343 
344  memcpy (args->mac_addr + 2, &rnd, sizeof (rnd));
345  args->mac_addr[0] = 2;
346  args->mac_addr[1] = 0xfe;
347  }
348  vif->rx_ring_sz = args->rx_ring_sz != 0 ? args->rx_ring_sz : 256;
349  vif->tx_ring_sz = args->tx_ring_sz != 0 ? args->tx_ring_sz : 256;
350  vif->host_if_name = args->host_if_name;
351  args->host_if_name = 0;
352  vif->net_ns = args->host_namespace;
353  args->host_namespace = 0;
354  vif->host_bridge = args->host_bridge;
355  args->host_bridge = 0;
356  clib_memcpy (vif->host_mac_addr, args->host_mac_addr, 6);
359  if (args->host_ip4_prefix_len)
360  clib_memcpy (&vif->host_ip4_addr, &args->host_ip4_addr, 4);
361  if (args->host_ip6_prefix_len)
362  clib_memcpy (&vif->host_ip6_addr, &args->host_ip6_addr, 16);
363 
365  vif->dev_instance,
366  args->mac_addr,
367  &vif->hw_if_index,
369  if (args->error)
370  {
371  args->rv = VNET_API_ERROR_INVALID_REGISTRATION;
372  goto error;
373  }
374 
375  tm->tap_ids = clib_bitmap_set (tm->tap_ids, vif->id, 1);
376  sw = vnet_get_hw_sw_interface (vnm, vif->hw_if_index);
377  vif->sw_if_index = sw->sw_if_index;
378  args->sw_if_index = vif->sw_if_index;
379  hw = vnet_get_hw_interface (vnm, vif->hw_if_index);
382  virtio_input_node.index);
386  vif->per_interface_next_index = ~0;
387  vif->type = VIRTIO_IF_TYPE_TAP;
388  vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP;
391  if (thm->n_vlib_mains > 1)
392  clib_spinlock_init (&vif->lockp);
393  goto done;
394 
395 error:
396  if (err)
397  {
398  ASSERT (args->error == 0);
399  args->error = err;
400  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
401  }
402  if (vif->tap_fd != -1)
403  close (vif->tap_fd);
404  if (vif->fd != -1)
405  close (vif->fd);
406  vec_foreach_index (i, vif->vrings) virtio_vring_free (vm, vif, i);
407  vec_free (vif->vrings);
408  memset (vif, 0, sizeof (virtio_if_t));
409  pool_put (vim->interfaces, vif);
410 
411 done:
412  if (vhost_mem)
413  clib_mem_free (vhost_mem);
414  if (old_netns_fd != -1)
415  close (old_netns_fd);
416 }
417 
418 int
419 tap_delete_if (vlib_main_t * vm, u32 sw_if_index)
420 {
421  vnet_main_t *vnm = vnet_get_main ();
422  virtio_main_t *mm = &virtio_main;
423  tap_main_t *tm = &tap_main;
424  int i;
425  virtio_if_t *vif;
427 
428  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
429  if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
430  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
431 
432  vif = pool_elt_at_index (mm->interfaces, hw->dev_instance);
433 
434  /* bring down the interface */
438 
440  vif->hw_if_index = ~0;
441 
442  if (vif->tap_fd != -1)
443  close (vif->tap_fd);
444  if (vif->fd != -1)
445  close (vif->fd);
446 
447  vec_foreach_index (i, vif->vrings) virtio_vring_free (vm, vif, i);
448  vec_free (vif->vrings);
449 
450  tm->tap_ids = clib_bitmap_set (tm->tap_ids, vif->id, 0);
451  clib_spinlock_free (&vif->lockp);
452  memset (vif, 0, sizeof (*vif));
453  pool_put (mm->interfaces, vif);
454 
455  return 0;
456 }
457 
458 int
460 {
461  vnet_main_t *vnm = vnet_get_main ();
462  virtio_main_t *mm = &virtio_main;
463  virtio_if_t *vif;
465  tap_interface_details_t *r_tapids = NULL;
466  tap_interface_details_t *tapid = NULL;
467 
468  /* *INDENT-OFF* */
469  pool_foreach (vif, mm->interfaces,
470  vec_add2(r_tapids, tapid, 1);
471  memset (tapid, 0, sizeof (*tapid));
472  tapid->id = vif->id;
473  tapid->sw_if_index = vif->sw_if_index;
474  hi = vnet_get_hw_interface (vnm, vif->hw_if_index);
475  clib_memcpy(tapid->dev_name, hi->name,
476  MIN (ARRAY_LEN (tapid->dev_name) - 1,
477  strlen ((const char *) hi->name)));
478  tapid->rx_ring_sz = vif->rx_ring_sz;
479  tapid->tx_ring_sz = vif->tx_ring_sz;
480  clib_memcpy(tapid->host_mac_addr, vif->host_mac_addr, 6);
481  if (vif->host_if_name)
482  {
484  MIN (ARRAY_LEN (tapid->host_if_name) - 1,
485  strlen ((const char *) vif->host_if_name)));
486  }
487  if (vif->net_ns)
488  {
489  clib_memcpy(tapid->host_namespace, vif->net_ns,
490  MIN (ARRAY_LEN (tapid->host_namespace) - 1,
491  strlen ((const char *) vif->net_ns)));
492  }
493  if (vif->host_bridge)
494  {
495  clib_memcpy(tapid->host_bridge, vif->host_bridge,
496  MIN (ARRAY_LEN (tapid->host_bridge) - 1,
497  strlen ((const char *) vif->host_bridge)));
498  }
499  if (vif->host_ip4_prefix_len)
500  clib_memcpy(tapid->host_ip4_addr, &vif->host_ip4_addr, 4);
502  if (vif->host_ip6_prefix_len)
503  clib_memcpy(tapid->host_ip6_addr, &vif->host_ip6_addr, 16);
505  );
506  /* *INDENT-ON* */
507 
508  *out_tapids = r_tapids;
509 
510  return 0;
511 }
512 
513 static clib_error_t *
515 {
516  tap_main_t *tm = &tap_main;
517  clib_error_t *error = 0;
518 
519  tm->log_default = vlib_log_register_class ("tap", 0);
520  vlib_log_debug (tm->log_default, "initialized");
521 
522  return error;
523 }
524 
526 
527 /*
528  * fd.io coding-style-patch-verification: ON
529  *
530  * Local Variables:
531  * eval: (c-set-style "gnu")
532  * End:
533  */
u32 per_interface_next_index
Definition: virtio.h:100
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:221
vmrglw vmrglh hi
#define vec_foreach_index(var, v)
Iterate over vector indices.
uword * tap_ids
Definition: tap.h:74
vlib_node_registration_t virtio_input_node
(constructor) VLIB_REGISTER_NODE (virtio_input_node)
Definition: node.c:277
virtio_if_t * interfaces
Definition: virtio.h:124
static u32 virtio_eth_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
Definition: tap.c:52
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:541
vlib_log_class_t log_default
Definition: tap.h:71
ip4_address_t host_ip4_addr
Definition: virtio.h:114
u8 host_if_name[64]
Definition: tap.h:59
u8 host_namespace[64]
Definition: tap.h:60
ip4_address_t host_ip4_addr
Definition: tap.h:36
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:321
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
u32 dev_instance
Definition: virtio.h:97
#define NULL
Definition: clib.h:55
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:225
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:41
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:562
int i
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:419
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:458
virtio_vring_t * vrings
Definition: virtio.h:103
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:228
int tap_dump_ifs(tap_interface_details_t **out_tapids)
Definition: tap.c:459
u8 host_ip4_gw_set
Definition: tap.h:39
unsigned char u8
Definition: types.h:56
double f64
Definition: types.h:142
static void clib_spinlock_free(clib_spinlock_t *p)
Definition: lock.h:64
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
u8 host_bridge[64]
Definition: tap.h:61
u8 host_ip6_addr[16]
Definition: tap.h:64
u64 features
Definition: virtio.h:105
u32 hw_if_index
Definition: virtio.h:98
u8 host_mac_addr[6]
Definition: tap.h:58
u8 host_ip6_prefix_len
Definition: virtio.h:117
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:443
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:156
u8 * host_bridge
Definition: virtio.h:112
int ifindex
Definition: virtio.h:119
int tap_delete_if(vlib_main_t *vm, u32 sw_if_index)
Definition: tap.c:419
#define clib_error_return(e, args...)
Definition: error.h:99
u8 host_mac_addr[6]
Definition: tap.h:34
unsigned int u32
Definition: types.h:88
#define vlib_log_debug(...)
Definition: log.h:54
#define MIN(x, y)
Definition: node.h:31
u32 id
Definition: virtio.h:96
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:57
u8 host_ip4_addr[4]
Definition: tap.h:62
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:464
int tap_fd
Definition: virtio.h:102
#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:274
u16 tx_ring_sz
Definition: virtio.h:108
ip4_address_t host_ip4_gw
Definition: tap.h:38
clib_spinlock_t lockp
Definition: virtio.h:94
ip6_address_t host_ip6_addr
Definition: tap.h:40
#define VNET_HW_INTERFACE_FLAG_SUPPORTS_INT_MODE
Definition: interface.h:496
u8 host_ip4_prefix_len
Definition: tap.h:37
u32 flags
Definition: vhost_user.h:110
static int ethernet_mac_address_is_zero(u8 *mac)
Definition: ethernet.h:65
vlib_main_t * vm
Definition: buffer.c:294
#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:339
ip6_address_t host_ip6_addr
Definition: virtio.h:116
#define clib_memcpy(a, b, c)
Definition: string.h:75
u8 * net_ns
Definition: virtio.h:111
u32 flags
Definition: virtio.h:93
#define ARRAY_LEN(x)
Definition: clib.h:59
static uword clib_bitmap_get(uword *ai, uword i)
Gets the ith bit value from a bitmap.
Definition: bitmap.h:197
u16 rx_ring_sz
Definition: virtio.h:109
u8 * host_bridge
Definition: tap.h:35
virtio_if_type_t type
Definition: virtio.h:107
#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:138
u64 remote_features
Definition: virtio.h:105
ip6_address_t host_ip6_gw
Definition: tap.h:42
clib_error_t * virtio_vring_init(vlib_main_t *vm, virtio_if_t *vif, u16 idx, u16 sz)
Definition: virtio.c:63
u8 * host_if_name
Definition: tap.h:33
u8 host_mac_addr[6]
Definition: virtio.h:113
static void clib_mem_free(void *p)
Definition: mem.h:179
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
Definition: interface.c:275
clib_error_t * virtio_vring_free(vlib_main_t *vm, virtio_if_t *vif, u32 idx)
Definition: virtio.c:155
unsigned int if_nametoindex(const char *ifname)
static void * clib_mem_alloc(uword size)
Definition: mem.h:112
virtio_main_t virtio_main
Definition: virtio.c:35
u8 host_ip6_gw_set
Definition: tap.h:43
void tap_create_if(vlib_main_t *vm, tap_create_if_args_t *args)
Definition: tap.c:81
tap_main_t tap_main
Definition: tap.c:42
int fd
Definition: virtio.h:101
u8 mac_addr[6]
Definition: tap.h:29
Definition: tap.h:68
clib_error_t * error
Definition: tap.h:47
u8 host_ip4_prefix_len
Definition: virtio.h:115
int vnet_hw_interface_unassign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.c:187
u32 sw_if_index
Definition: virtio.h:99
static u32 random_u32(u32 *seed)
32-bit random number generator
Definition: random.h:69
TAP interface details struct.
Definition: tap.h:51
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:549
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:252
u8 * host_namespace
Definition: tap.h:32
static uword clib_bitmap_first_clear(uword *ai)
Return the lowest numbered clear bit in a bitmap.
Definition: bitmap.h:445
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: devices.h:79
static clib_error_t * tap_init(vlib_main_t *vm)
Definition: tap.c:514
u8 * host_if_name
Definition: virtio.h:110