summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vnet/devices/tap/tap.c41
-rw-r--r--src/vnet/devices/tap/tap.h2
-rw-r--r--src/vnet/devices/virtio/virtio.c1
-rw-r--r--src/vnet/devices/virtio/virtio.h1
4 files changed, 45 insertions, 0 deletions
diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c
index aa9182a58f7..94a91e5509a 100644
--- a/src/vnet/devices/tap/tap.c
+++ b/src/vnet/devices/tap/tap.c
@@ -751,6 +751,12 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
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;
@@ -987,6 +993,41 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids)
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)
{
diff --git a/src/vnet/devices/tap/tap.h b/src/vnet/devices/tap/tap.h
index 46f13a4e274..42283281448 100644
--- a/src/vnet/devices/tap/tap.h
+++ b/src/vnet/devices/tap/tap.h
@@ -108,6 +108,8 @@ int
tap_csum_offload_enable_disable (vlib_main_t * vm, u32 sw_if_index,
int enable_disable);
int tap_dump_ifs (tap_interface_details_t ** out_tapids);
+int tap_set_carrier (u32 hw_if_index, u32 carrier_up);
+
#endif /* _VNET_DEVICES_VIRTIO_TAP_H_ */
diff --git a/src/vnet/devices/virtio/virtio.c b/src/vnet/devices/virtio/virtio.c
index 8209a46b52f..925ad092b91 100644
--- a/src/vnet/devices/virtio/virtio.c
+++ b/src/vnet/devices/virtio/virtio.c
@@ -345,6 +345,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type)
if (type == VIRTIO_IF_TYPE_TAP)
vlib_cli_output (vm, " host-mac-addr: %U",
format_ethernet_address, vif->host_mac_addr);
+ vlib_cli_output (vm, " host-carrier-up: %u", vif->host_carrier_up);
vec_foreach_index (i, vif->vhost_fds)
str = format (str, " %d", vif->vhost_fds[i]);
diff --git a/src/vnet/devices/virtio/virtio.h b/src/vnet/devices/virtio/virtio.h
index 86660a1f933..fda72365db9 100644
--- a/src/vnet/devices/virtio/virtio.h
+++ b/src/vnet/devices/virtio/virtio.h
@@ -169,6 +169,7 @@ typedef struct
ip4_address_t host_ip4_addr;
u8 host_ip4_prefix_len;
u8 host_ip6_prefix_len;
+ u8 host_carrier_up; /* host tun/tap driver link carrier state */
};
struct /* native virtio */
{