From 9b71ba20ac555c98d92b71a7567135c19ad7610c Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Fri, 5 Jun 2020 12:00:34 +0100 Subject: [PATCH] vmm, vm-virtio: Stop always autogenerating a host MAC address This removes the need to use CAP_NET_ADMIN privileges and instead the host MAC addres is either provided by the user or alternatively it is retrieved from the kernel. TEST=Run cloud-hypervisor without CAP_NET_ADMIN permission and a preconfigured tap device: sudo ip tuntap add name tap0 mode tap sudo ifconfig tap0 192.168.249.1 netmask 255.255.255.0 up cargo clean cargo build target/debug/cloud-hypervisor --serial tty --console off --kernel ~/src/rust-hypervisor-firmware/target/target/release/hypervisor-fw --disk path=~/workloads/clear-33190-kvm.img --net tap=tap0 VM was also rebooted to check that works correctly. Fixes: #1274 Signed-off-by: Rob Bradford --- vhost_user_net/src/lib.rs | 2 +- vm-virtio/src/net.rs | 2 +- vm-virtio/src/net_util.rs | 8 ++++++-- vmm/src/config.rs | 21 +++++++++------------ vmm/src/device_manager.rs | 12 ++++++++---- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/vhost_user_net/src/lib.rs b/vhost_user_net/src/lib.rs index 37f8ebd5c..2cc43a065 100644 --- a/vhost_user_net/src/lib.rs +++ b/vhost_user_net/src/lib.rs @@ -141,7 +141,7 @@ impl VhostUserNetBackend { ifname, Some(ip_addr), Some(netmask), - Some(host_mac), + &mut Some(host_mac), num_queues / 2, ) .map_err(Error::OpenTap)?; diff --git a/vm-virtio/src/net.rs b/vm-virtio/src/net.rs index 6c3da0bb1..a8a650789 100644 --- a/vm-virtio/src/net.rs +++ b/vm-virtio/src/net.rs @@ -465,7 +465,7 @@ impl Net { ip_addr: Option, netmask: Option, guest_mac: Option, - host_mac: Option, + host_mac: &mut Option, iommu: bool, num_queues: usize, queue_size: u16, diff --git a/vm-virtio/src/net_util.rs b/vm-virtio/src/net_util.rs index 2568749c0..66b6af2ad 100644 --- a/vm-virtio/src/net_util.rs +++ b/vm-virtio/src/net_util.rs @@ -122,6 +122,8 @@ pub enum Error { TapSetNetmask(TapError), /// Setting MAC address failed TapSetMac(TapError), + /// Getting MAC address failed + TapGetMac(TapError), /// Setting tap interface offload flags failed. TapSetOffload(TapError), /// Setting vnet header size failed. @@ -539,7 +541,7 @@ pub fn open_tap( if_name: Option<&str>, ip_addr: Option, netmask: Option, - host_mac: Option, + host_mac: &mut Option, num_rx_q: usize, ) -> Result> { let mut taps: Vec = Vec::new(); @@ -568,7 +570,9 @@ pub fn open_tap( tap.set_netmask(mask).map_err(Error::TapSetNetmask)?; } if let Some(mac) = host_mac { - tap.set_mac_addr(mac).map_err(Error::TapSetMac)? + tap.set_mac_addr(*mac).map_err(Error::TapSetMac)? + } else { + *host_mac = Some(tap.get_mac_addr().map_err(Error::TapGetMac)?) } tap.enable().map_err(Error::TapEnable)?; tap.set_offload(flag).map_err(Error::TapSetOffload)?; diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 8cc5321e7..45e64b012 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -683,8 +683,8 @@ pub struct NetConfig { pub mask: Ipv4Addr, #[serde(default = "default_netconfig_mac")] pub mac: MacAddr, - #[serde(default = "default_netconfig_mac")] - pub host_mac: MacAddr, + #[serde(default)] + pub host_mac: Option, #[serde(default)] pub iommu: bool, #[serde(default = "default_netconfig_num_queues")] @@ -729,7 +729,7 @@ impl Default for NetConfig { ip: default_netconfig_ip(), mask: default_netconfig_mask(), mac: default_netconfig_mac(), - host_mac: default_netconfig_mac(), + host_mac: None, iommu: false, num_queues: default_netconfig_num_queues(), queue_size: default_netconfig_queue_size(), @@ -776,10 +776,7 @@ impl NetConfig { .convert("mac") .map_err(Error::ParseNetwork)? .unwrap_or_else(default_netconfig_mac); - let host_mac = parser - .convert("host_mac") - .map_err(Error::ParseNetwork)? - .unwrap_or_else(default_netconfig_mac); + let host_mac = parser.convert("host_mac").map_err(Error::ParseNetwork)?; let iommu = parser .convert::("iommu") .map_err(Error::ParseNetwork)? @@ -1633,7 +1630,7 @@ mod tests { NetConfig::parse("mac=de:ad:be:ef:12:34,host_mac=12:34:de:ad:be:ef")?, NetConfig { mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(), - host_mac: MacAddr::parse_str("12:34:de:ad:be:ef").unwrap(), + host_mac: Some(MacAddr::parse_str("12:34:de:ad:be:ef").unwrap()), ..Default::default() } ); @@ -1642,7 +1639,7 @@ mod tests { NetConfig::parse("mac=de:ad:be:ef:12:34,host_mac=12:34:de:ad:be:ef,id=mynet0")?, NetConfig { mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(), - host_mac: MacAddr::parse_str("12:34:de:ad:be:ef").unwrap(), + host_mac: Some(MacAddr::parse_str("12:34:de:ad:be:ef").unwrap()), id: Some("mynet0".to_owned()), ..Default::default() } @@ -1654,7 +1651,7 @@ mod tests { )?, NetConfig { mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(), - host_mac: MacAddr::parse_str("12:34:de:ad:be:ef").unwrap(), + host_mac: Some(MacAddr::parse_str("12:34:de:ad:be:ef").unwrap()), tap: Some("tap0".to_owned()), ip: "192.168.100.1".parse().unwrap(), mask: "255.255.255.128".parse().unwrap(), @@ -1668,7 +1665,7 @@ mod tests { )?, NetConfig { mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(), - host_mac: MacAddr::parse_str("12:34:de:ad:be:ef").unwrap(), + host_mac: Some(MacAddr::parse_str("12:34:de:ad:be:ef").unwrap()), vhost_user: true, vhost_socket: Some("/tmp/sock".to_owned()), ..Default::default() @@ -1679,7 +1676,7 @@ mod tests { NetConfig::parse("mac=de:ad:be:ef:12:34,host_mac=12:34:de:ad:be:ef,num_queues=4,queue_size=1024,iommu=on")?, NetConfig { mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(), - host_mac: MacAddr::parse_str("12:34:de:ad:be:ef").unwrap(), + host_mac: Some(MacAddr::parse_str("12:34:de:ad:be:ef").unwrap()), num_queues: 4, queue_size: 1024, iommu: true, diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index c0ba9e1ca..da232191b 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -1512,13 +1512,17 @@ impl DeviceManager { .args(&[ "--net-backend", &format!( - "ip={},mask={},socket={},num_queues={},queue_size={},host_mac={}", + "ip={},mask={},socket={},num_queues={},queue_size={}{}", net_cfg.ip, net_cfg.mask, &socket, net_cfg.num_queues, net_cfg.queue_size, - net_cfg.host_mac + if let Some(mac) = net_cfg.host_mac { + format!(",host_mac={:}", mac) + } else { + "".to_owned() + } ), ]) .spawn() @@ -1583,7 +1587,7 @@ impl DeviceManager { None, None, Some(net_cfg.mac), - Some(net_cfg.host_mac), + &mut net_cfg.host_mac, net_cfg.iommu, net_cfg.num_queues, net_cfg.queue_size, @@ -1598,7 +1602,7 @@ impl DeviceManager { Some(net_cfg.ip), Some(net_cfg.mask), Some(net_cfg.mac), - Some(net_cfg.host_mac), + &mut net_cfg.host_mac, net_cfg.iommu, net_cfg.num_queues, net_cfg.queue_size,