From e37f63282ce3d6f5adb1bc854514181aca493ecf Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Fri, 17 Jul 2026 05:42:50 -0700 Subject: [PATCH] net_util: Only set host MAC address from user input In case the host MAC address associated with a TAP device wasn't explicitly provided by the user, Cloud Hypervisor would get the host MAC associated by default with this TAP device and store it through the network config. Problem is, in the context of a snapshot/restore, that meant the network config provided by the user was different on the destination host compared to the source host. This was causing an issue when Cloud Hypervisor wasn't started with CAP_NET_ADMIN permissions as it couldn't set the host MAC address on the destination, while the source never needed these permissions since the MAC was automatically allocated by the kernel. We're fixing this issue by setting the host MAC address when it's explicitly requested by the user through the network config, and making the host MAC immutable so that it can't be changed at runtime. Signed-off-by: Sebastien Boeuf --- cloud-hypervisor/tests/common/tests_wrappers.rs | 2 +- cloud-hypervisor/tests/integration.rs | 4 ++-- net_util/src/open_tap.rs | 10 +++------- vhost_user_net/src/lib.rs | 2 +- virtio-devices/src/net.rs | 2 +- vmm/src/device_manager.rs | 4 ++-- 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/cloud-hypervisor/tests/common/tests_wrappers.rs b/cloud-hypervisor/tests/common/tests_wrappers.rs index d88e6d139..046406d0b 100644 --- a/cloud-hypervisor/tests/common/tests_wrappers.rs +++ b/cloud-hypervisor/tests/common/tests_wrappers.rs @@ -3261,7 +3261,7 @@ pub(crate) fn _test_tap_from_fd(guest: &Guest) { Ipv4Addr::from_str(&guest.network.host_ip0).unwrap(), )), None, - &mut None, + None, None, num_queue_pairs, Some(libc::O_RDWR | libc::O_NONBLOCK), diff --git a/cloud-hypervisor/tests/integration.rs b/cloud-hypervisor/tests/integration.rs index 42ac193a7..10d0f023b 100644 --- a/cloud-hypervisor/tests/integration.rs +++ b/cloud-hypervisor/tests/integration.rs @@ -9461,7 +9461,7 @@ mod common_sequential { Ipv4Addr::from_str(&guest.network.host_ip0).unwrap(), )), None, - &mut None, + None, None, num_queue_pairs, Some(libc::O_RDWR | libc::O_NONBLOCK), @@ -9565,7 +9565,7 @@ mod common_sequential { Ipv4Addr::from_str(&guest.network.host_ip0).unwrap(), )), None, - &mut None, + None, None, num_queue_pairs, Some(libc::O_RDWR | libc::O_NONBLOCK), diff --git a/net_util/src/open_tap.rs b/net_util/src/open_tap.rs index 6cc8b2a37..9d342342b 100644 --- a/net_util/src/open_tap.rs +++ b/net_util/src/open_tap.rs @@ -27,8 +27,6 @@ pub enum Error { TapSetIpNetmask(#[source] TapError), #[error("Setting MAC address failed")] TapSetMac(#[source] TapError), - #[error("Getting MAC address failed")] - TapGetMac(#[source] TapError), #[error("Setting vnet header size failed")] TapSetVnetHdrSize(#[source] TapError), #[error("Setting MTU failed")] @@ -66,7 +64,7 @@ fn open_tap_rx_q_0( if_name: Option<&str>, ip_addr: Option, netmask: Option, - host_mac: &mut Option, + host_mac: Option, mtu: Option, num_rx_q: usize, flags: Option, @@ -90,9 +88,7 @@ fn open_tap_rx_q_0( .map_err(Error::TapSetIpNetmask)?; } if let Some(mac) = host_mac { - tap.set_mac_addr(*mac).map_err(Error::TapSetMac)?; - } else { - *host_mac = Some(tap.get_mac_addr().map_err(Error::TapGetMac)?); + tap.set_mac_addr(mac).map_err(Error::TapSetMac)?; } if let Some(mtu) = mtu { tap.set_mtu(mtu as i32).map_err(Error::TapSetMtu)?; @@ -111,7 +107,7 @@ pub fn open_tap( if_name: Option<&str>, ip_addr: Option, netmask: Option, - host_mac: &mut Option, + host_mac: Option, mtu: Option, num_rx_q: usize, flags: Option, diff --git a/vhost_user_net/src/lib.rs b/vhost_user_net/src/lib.rs index 6278e2457..c9548d4eb 100644 --- a/vhost_user_net/src/lib.rs +++ b/vhost_user_net/src/lib.rs @@ -134,7 +134,7 @@ impl VhostUserNetBackend { ifname, Some(ip_addr), Some(netmask), - &mut Some(host_mac), + Some(host_mac), mtu, num_queues / 2, None, diff --git a/virtio-devices/src/net.rs b/virtio-devices/src/net.rs index 0a2a8a6ce..a1dff51b8 100644 --- a/virtio-devices/src/net.rs +++ b/virtio-devices/src/net.rs @@ -656,7 +656,7 @@ impl Net { ip_addr: Option, netmask: Option, guest_mac: Option, - host_mac: &mut Option, + host_mac: Option, mtu: Option, access_platform_enabled: bool, num_queues: usize, diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 0eea684ff..95d546877 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -2979,7 +2979,7 @@ impl DeviceManager { net_cfg.ip, net_cfg.mask, Some(net_cfg.mac), - &mut net_cfg.host_mac, + net_cfg.host_mac, net_cfg.mtu, self.force_access_platform | net_cfg.pci_common.iommu, net_cfg.num_queues, @@ -3030,7 +3030,7 @@ impl DeviceManager { net_cfg.ip, net_cfg.mask, Some(net_cfg.mac), - &mut net_cfg.host_mac, + net_cfg.host_mac, net_cfg.mtu, self.force_access_platform | net_cfg.pci_common.iommu, net_cfg.num_queues,