summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohsin Kazmi <sykazmi@cisco.com>2019-04-17 12:06:57 +0200
committerDave Barach <openvpp@barachs.net>2019-04-17 14:33:50 +0000
commite4ac48e792f4eebfce296cfde844ee73b1abd62f (patch)
tree491e4422433a1c2d57dcd23d1b392f9aca4537e5
parenta7dd0c8a278c1735eb6b0f75749a0d76dac350b3 (diff)
tap: clean-up when linux will delete the tap interface
When container is deleted which has tap interface attached, Linux also delete the tap interface leaving the VPP side of tap. This patch does a clean up job to remove that VPP side of tap interface. To produce the behavior: In VPP: create tap On linux: sudo ip netns add ns1 sudo ip link set dev tap0 netns ns1 sudo ip netns del ns1 Change-Id: Iaed1700073a9dc64e626c1d0c449f466c143f3ae Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
-rw-r--r--src/vnet/devices/tap/tap.c42
-rw-r--r--src/vnet/devices/virtio/virtio.h1
2 files changed, 43 insertions, 0 deletions
diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c
index 91d4a811ad8..a1a9fee2d77 100644
--- a/src/vnet/devices/tap/tap.c
+++ b/src/vnet/devices/tap/tap.c
@@ -57,6 +57,38 @@ virtio_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi,
return 0;
}
+void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
+
+static clib_error_t *
+call_tap_read_ready (clib_file_t * uf)
+{
+ /* nothing to do */
+ return 0;
+}
+
+static void
+tap_delete_if_cp (u32 * sw_if_index)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ tap_delete_if (vm, *sw_if_index);
+}
+
+/*
+ * Tap clean-up routine:
+ * Linux side of tap interface can be deleted i.e. tap is
+ * attached to container and if someone will delete this
+ * container, will also removes tap interface. While VPP
+ * will have other side of tap. This function will RPC
+ * main thread to call the tap_delete_if to cleanup tap.
+ */
+static clib_error_t *
+call_tap_error_ready (clib_file_t * uf)
+{
+ vl_api_rpc_call_main_thread (tap_delete_if_cp, (u8 *) & uf->private_data,
+ sizeof (uf->private_data));
+ return 0;
+}
+
static int
open_netns_fd (char *netns)
{
@@ -92,6 +124,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
size_t hdrsz;
struct vhost_memory *vhost_mem = 0;
virtio_if_t *vif = 0;
+ clib_file_t t = { 0 };
clib_error_t *err = 0;
int fd = -1;
@@ -407,6 +440,14 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
VNET_HW_INTERFACE_FLAG_LINK_UP);
vif->cxq_vring = NULL;
+ t.read_function = call_tap_read_ready;
+ t.error_function = call_tap_error_ready;
+ t.file_descriptor = vif->tap_fd;
+ t.private_data = vif->sw_if_index;
+ t.description = format (0, "tap sw_if_index %u fd: %u",
+ vif->sw_if_index, vif->tap_fd);
+ vif->tap_file_index = clib_file_add (&file_main, &t);
+
if (thm->n_vlib_mains > 1)
clib_spinlock_init (&vif->lockp);
goto done;
@@ -463,6 +504,7 @@ tap_delete_if (vlib_main_t * vm, u32 sw_if_index)
if (hw->flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO)
vnm->interface_main.gso_interface_count--;
+ clib_file_del_by_index (&file_main, vif->tap_file_index);
/* bring down the interface */
vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
vnet_sw_interface_set_flags (vnm, vif->sw_if_index, 0);
diff --git a/src/vnet/devices/virtio/virtio.h b/src/vnet/devices/virtio/virtio.h
index 1de704386a8..5177dbabce4 100644
--- a/src/vnet/devices/virtio/virtio.h
+++ b/src/vnet/devices/virtio/virtio.h
@@ -180,6 +180,7 @@ typedef struct
u8 host_ip4_prefix_len;
ip6_address_t host_ip6_addr;
u8 host_ip6_prefix_len;
+ u32 tap_file_index;
int gso_enabled;
int ifindex;
virtio_vring_t *cxq_vring;