diff options
author | Mohsin Kazmi <sykazmi@cisco.com> | 2019-04-17 12:06:57 +0200 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2019-04-17 14:33:50 +0000 |
commit | e4ac48e792f4eebfce296cfde844ee73b1abd62f (patch) | |
tree | 491e4422433a1c2d57dcd23d1b392f9aca4537e5 /src/vnet/devices/tap | |
parent | a7dd0c8a278c1735eb6b0f75749a0d76dac350b3 (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>
Diffstat (limited to 'src/vnet/devices/tap')
-rw-r--r-- | src/vnet/devices/tap/tap.c | 42 |
1 files changed, 42 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); |