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 <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2020-06-05 12:00:34 +01:00 committed by Sebastien Boeuf
parent 1f8b6fa947
commit 9b71ba20ac
5 changed files with 25 additions and 20 deletions

View File

@ -141,7 +141,7 @@ impl VhostUserNetBackend {
ifname, ifname,
Some(ip_addr), Some(ip_addr),
Some(netmask), Some(netmask),
Some(host_mac), &mut Some(host_mac),
num_queues / 2, num_queues / 2,
) )
.map_err(Error::OpenTap)?; .map_err(Error::OpenTap)?;

View File

@ -465,7 +465,7 @@ impl Net {
ip_addr: Option<Ipv4Addr>, ip_addr: Option<Ipv4Addr>,
netmask: Option<Ipv4Addr>, netmask: Option<Ipv4Addr>,
guest_mac: Option<MacAddr>, guest_mac: Option<MacAddr>,
host_mac: Option<MacAddr>, host_mac: &mut Option<MacAddr>,
iommu: bool, iommu: bool,
num_queues: usize, num_queues: usize,
queue_size: u16, queue_size: u16,

View File

@ -122,6 +122,8 @@ pub enum Error {
TapSetNetmask(TapError), TapSetNetmask(TapError),
/// Setting MAC address failed /// Setting MAC address failed
TapSetMac(TapError), TapSetMac(TapError),
/// Getting MAC address failed
TapGetMac(TapError),
/// Setting tap interface offload flags failed. /// Setting tap interface offload flags failed.
TapSetOffload(TapError), TapSetOffload(TapError),
/// Setting vnet header size failed. /// Setting vnet header size failed.
@ -539,7 +541,7 @@ pub fn open_tap(
if_name: Option<&str>, if_name: Option<&str>,
ip_addr: Option<Ipv4Addr>, ip_addr: Option<Ipv4Addr>,
netmask: Option<Ipv4Addr>, netmask: Option<Ipv4Addr>,
host_mac: Option<MacAddr>, host_mac: &mut Option<MacAddr>,
num_rx_q: usize, num_rx_q: usize,
) -> Result<Vec<Tap>> { ) -> Result<Vec<Tap>> {
let mut taps: Vec<Tap> = Vec::new(); let mut taps: Vec<Tap> = Vec::new();
@ -568,7 +570,9 @@ pub fn open_tap(
tap.set_netmask(mask).map_err(Error::TapSetNetmask)?; tap.set_netmask(mask).map_err(Error::TapSetNetmask)?;
} }
if let Some(mac) = host_mac { 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.enable().map_err(Error::TapEnable)?;
tap.set_offload(flag).map_err(Error::TapSetOffload)?; tap.set_offload(flag).map_err(Error::TapSetOffload)?;

View File

@ -683,8 +683,8 @@ pub struct NetConfig {
pub mask: Ipv4Addr, pub mask: Ipv4Addr,
#[serde(default = "default_netconfig_mac")] #[serde(default = "default_netconfig_mac")]
pub mac: MacAddr, pub mac: MacAddr,
#[serde(default = "default_netconfig_mac")] #[serde(default)]
pub host_mac: MacAddr, pub host_mac: Option<MacAddr>,
#[serde(default)] #[serde(default)]
pub iommu: bool, pub iommu: bool,
#[serde(default = "default_netconfig_num_queues")] #[serde(default = "default_netconfig_num_queues")]
@ -729,7 +729,7 @@ impl Default for NetConfig {
ip: default_netconfig_ip(), ip: default_netconfig_ip(),
mask: default_netconfig_mask(), mask: default_netconfig_mask(),
mac: default_netconfig_mac(), mac: default_netconfig_mac(),
host_mac: default_netconfig_mac(), host_mac: None,
iommu: false, iommu: false,
num_queues: default_netconfig_num_queues(), num_queues: default_netconfig_num_queues(),
queue_size: default_netconfig_queue_size(), queue_size: default_netconfig_queue_size(),
@ -776,10 +776,7 @@ impl NetConfig {
.convert("mac") .convert("mac")
.map_err(Error::ParseNetwork)? .map_err(Error::ParseNetwork)?
.unwrap_or_else(default_netconfig_mac); .unwrap_or_else(default_netconfig_mac);
let host_mac = parser let host_mac = parser.convert("host_mac").map_err(Error::ParseNetwork)?;
.convert("host_mac")
.map_err(Error::ParseNetwork)?
.unwrap_or_else(default_netconfig_mac);
let iommu = parser let iommu = parser
.convert::<Toggle>("iommu") .convert::<Toggle>("iommu")
.map_err(Error::ParseNetwork)? .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::parse("mac=de:ad:be:ef:12:34,host_mac=12:34:de:ad:be:ef")?,
NetConfig { NetConfig {
mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(), 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() ..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::parse("mac=de:ad:be:ef:12:34,host_mac=12:34:de:ad:be:ef,id=mynet0")?,
NetConfig { NetConfig {
mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(), 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()), id: Some("mynet0".to_owned()),
..Default::default() ..Default::default()
} }
@ -1654,7 +1651,7 @@ mod tests {
)?, )?,
NetConfig { NetConfig {
mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(), 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()), tap: Some("tap0".to_owned()),
ip: "192.168.100.1".parse().unwrap(), ip: "192.168.100.1".parse().unwrap(),
mask: "255.255.255.128".parse().unwrap(), mask: "255.255.255.128".parse().unwrap(),
@ -1668,7 +1665,7 @@ mod tests {
)?, )?,
NetConfig { NetConfig {
mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(), 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_user: true,
vhost_socket: Some("/tmp/sock".to_owned()), vhost_socket: Some("/tmp/sock".to_owned()),
..Default::default() ..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::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 { NetConfig {
mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(), 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, num_queues: 4,
queue_size: 1024, queue_size: 1024,
iommu: true, iommu: true,

View File

@ -1512,13 +1512,17 @@ impl DeviceManager {
.args(&[ .args(&[
"--net-backend", "--net-backend",
&format!( &format!(
"ip={},mask={},socket={},num_queues={},queue_size={},host_mac={}", "ip={},mask={},socket={},num_queues={},queue_size={}{}",
net_cfg.ip, net_cfg.ip,
net_cfg.mask, net_cfg.mask,
&socket, &socket,
net_cfg.num_queues, net_cfg.num_queues,
net_cfg.queue_size, net_cfg.queue_size,
net_cfg.host_mac if let Some(mac) = net_cfg.host_mac {
format!(",host_mac={:}", mac)
} else {
"".to_owned()
}
), ),
]) ])
.spawn() .spawn()
@ -1583,7 +1587,7 @@ impl DeviceManager {
None, None,
None, None,
Some(net_cfg.mac), Some(net_cfg.mac),
Some(net_cfg.host_mac), &mut net_cfg.host_mac,
net_cfg.iommu, net_cfg.iommu,
net_cfg.num_queues, net_cfg.num_queues,
net_cfg.queue_size, net_cfg.queue_size,
@ -1598,7 +1602,7 @@ impl DeviceManager {
Some(net_cfg.ip), Some(net_cfg.ip),
Some(net_cfg.mask), Some(net_cfg.mask),
Some(net_cfg.mac), Some(net_cfg.mac),
Some(net_cfg.host_mac), &mut net_cfg.host_mac,
net_cfg.iommu, net_cfg.iommu,
net_cfg.num_queues, net_cfg.num_queues,
net_cfg.queue_size, net_cfg.queue_size,