From e4ac48e792f4eebfce296cfde844ee73b1abd62f Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Wed, 17 Apr 2019 12:06:57 +0200 Subject: [PATCH] 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 --- src/vnet/devices/tap/tap.c | 42 ++++++++++++++++++++++++++++++++++++++++ src/vnet/devices/virtio/virtio.h | 1 + 2 files changed, 43 insertions(+) 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; -- 2.16.6