virtio_vring_free_tx (vm, vif, TX_QUEUE (i));
/* *INDENT-ON* */
- _IOCTL (vif->tap_fds[0], TUNSETPERSIST, (void *) (uintptr_t) 0);
- tap_log_dbg (vif, "TUNSETPERSIST: unset");
+ if (vif->tap_fds)
+ {
+ _IOCTL (vif->tap_fds[0], TUNSETPERSIST, (void *) (uintptr_t) 0);
+ tap_log_dbg (vif, "TUNSETPERSIST: unset");
+ }
error:
vec_foreach_index (i, vif->tap_fds) close (vif->tap_fds[i]);
{
host_if_name = (char *) args->host_if_name;
clib_memcpy (ifr.ifr_name, host_if_name,
- clib_min (IFNAMSIZ, strlen (host_if_name)));
+ clib_min (IFNAMSIZ, vec_len (host_if_name)));
}
else
{
{
vnet_hw_interface_assign_rx_thread (vnm, vif->hw_if_index, i, ~0);
vnet_hw_interface_set_rx_mode (vnm, vif->hw_if_index, i,
- VNET_HW_INTERFACE_RX_MODE_DEFAULT);
+ VNET_HW_IF_RX_MODE_DEFAULT);
virtio_vring_set_numa_node (vm, vif, RX_QUEUE (i));
}
vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP;
vnet_hw_interface_set_flags (vnm, vif->hw_if_index,
VNET_HW_INTERFACE_FLAG_LINK_UP);
+ /*
+ * Host tun/tap driver link carrier state is "up" at creation. The
+ * driver never changes this unless the backend (VPP) changes it using
+ * TUNSETCARRIER ioctl(). See tap_set_carrier().
+ */
+ vif->host_carrier_up = 1;
vif->cxq_vring = NULL;
goto done;
{
clib_memcpy(tapid->host_if_name, vif->host_if_name,
MIN (ARRAY_LEN (tapid->host_if_name) - 1,
- strlen ((const char *) vif->host_if_name)));
+ vec_len (vif->host_if_name)));
}
if (vif->net_ns)
{
clib_memcpy(tapid->host_namespace, vif->net_ns,
MIN (ARRAY_LEN (tapid->host_namespace) - 1,
- strlen ((const char *) vif->net_ns)));
+ vec_len (vif->net_ns)));
}
if (vif->host_bridge)
{
clib_memcpy(tapid->host_bridge, vif->host_bridge,
MIN (ARRAY_LEN (tapid->host_bridge) - 1,
- strlen ((const char *) vif->host_bridge)));
+ vec_len (vif->host_bridge)));
}
if (vif->host_ip4_prefix_len)
clib_memcpy(tapid->host_ip4_addr.as_u8, &vif->host_ip4_addr, 4);
return 0;
}
+/*
+ * Set host tap/tun interface carrier state so it will appear to host
+ * applications that the interface's link state changed.
+ *
+ * If the kernel we're building against does not have support for the
+ * TUNSETCARRIER ioctl command, do nothing.
+ */
+int
+tap_set_carrier (u32 hw_if_index, u32 carrier_up)
+{
+ int ret = 0;
+#ifdef TUNSETCARRIER
+ vnet_main_t *vnm = vnet_get_main ();
+ vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
+ virtio_main_t *mm = &virtio_main;
+ virtio_if_t *vif;
+ int *fd;
+
+ vif = pool_elt_at_index (mm->interfaces, hi->dev_instance);
+ vec_foreach (fd, vif->tap_fds)
+ {
+ ret = ioctl (*fd, TUNSETCARRIER, &carrier_up);
+ if (ret < 0)
+ {
+ clib_warning ("ioctl (TUNSETCARRIER) returned %d", ret);
+ break;
+ }
+ }
+ if (!ret)
+ vif->host_carrier_up = (carrier_up != 0);
+#endif
+
+ return ret;
+}
+
static clib_error_t *
tap_mtu_config (vlib_main_t * vm, unformat_input_t * input)
{