From 764a8780c2ad250b76f289d742d22216d8c0904e Mon Sep 17 00:00:00 2001 From: Duncan Eastoe Date: Wed, 8 Sep 2021 19:11:33 +0100 Subject: tap: set device name on creation via TUNSETIFF Type: fix Currently when a new TAP/TUN device is created from tap_create_if() via the TUNSETIFF ioctl(), a name is allocated by the kernel (eg. tap0). If the caller supplied a name this is subsequently set via netlink, after the device has been created. Now we request the kernel to create the new device with the caller's requested name in the first instance, thus avoiding the need to rename the device, and therefore avoiding a window where the device exists with a different name. This can be beneficial, for example, when writing systemd-udevd link files [1]. Having the TAP/TUN devices created with the requested name ensures they can be correctly matched by the OriginalName option. Writing link files might be necessary, for example, to avoid VPP and systemd-udevd racing to set the MAC address on a newly created TAP interface. systemd-udevd can be configured to not manipulate the MAC addresses of matched interfaces. These changes also resolve an issue where the created device would not be renamed if the caller requested it be moved to a different network namespace, since vnet_netlink_set_link_name() was not called in that case. [1] https://www.freedesktop.org/software/systemd/man/systemd.link.html Signed-off-by: Duncan Eastoe Change-Id: I3d657632856d03979d6b914225c3c841c379e0a1 --- src/vnet/devices/tap/tap.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'src/vnet/devices') diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c index 33d6e3bc84a..8fca35df202 100644 --- a/src/vnet/devices/tap/tap.c +++ b/src/vnet/devices/tap/tap.c @@ -195,13 +195,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) if (args->tap_flags & TAP_FLAG_ATTACH) { - if (args->host_if_name != NULL) - { - host_if_name = (char *) args->host_if_name; - clib_memcpy (ifr.ifr_name, host_if_name, - clib_min (IFNAMSIZ, vec_len (host_if_name))); - } - else + if (args->host_if_name == NULL) { args->rv = VNET_API_ERROR_NO_MATCHING_INTERFACE; err = clib_error_return (0, "host_if_name is not provided"); @@ -227,6 +221,13 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) } } + if (args->host_if_name != NULL) + { + host_if_name = (char *) args->host_if_name; + clib_memcpy (ifr.ifr_name, host_if_name, + clib_min (IFNAMSIZ, vec_len (host_if_name))); + } + if ((tfd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0) { args->rv = VNET_API_ERROR_SYSCALL_ERROR_2; @@ -435,16 +436,6 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) goto error; } } - else if (host_if_name) - { - args->error = - vnet_netlink_set_link_name (vif->ifindex, host_if_name); - if (args->error) - { - args->rv = VNET_API_ERROR_NETLINK_ERROR; - goto error; - } - } } if (vif->type == VIRTIO_IF_TYPE_TAP) -- cgit 1.2.3-korg