vhost-user_net, vm-virtio, vmm: Permit host MAC address setting

Add a new "host_mac" parameter to "--net" and "--net-backend" and use
this to set the MAC address on the tap interface. If no address is given
one is randomly assigned and is stored in the config.

Support for vhost-user-net self spawning was also included.

Fixes: #1177

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2020-05-15 10:00:38 +01:00
parent 11049401ce
commit 1b8b5ac179
6 changed files with 79 additions and 35 deletions

View File

@ -798,11 +798,11 @@ mod unit_tests {
false, false,
), ),
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--net", "mac=12:34:56:78:90:ab"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--net", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd"}
] ]
}"#, }"#,
true, true,
@ -811,12 +811,12 @@ mod unit_tests {
vec![ vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0"}
] ]
}"#, }"#,
true, true,
@ -825,12 +825,12 @@ mod unit_tests {
vec![ vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4"}
] ]
}"#, }"#,
true, true,
@ -839,12 +839,12 @@ mod unit_tests {
vec![ vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"}
] ]
}"#, }"#,
true, true,
@ -853,12 +853,12 @@ mod unit_tests {
vec![ vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4}
] ]
}"#, }"#,
true, true,
@ -867,12 +867,12 @@ mod unit_tests {
vec![ vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4,queue_size=128", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4,queue_size=128",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4, "queue_size": 128} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4, "queue_size": 128}
] ]
}"#, }"#,
true, true,
@ -881,12 +881,12 @@ mod unit_tests {
vec![ vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"}
] ]
}"#, }"#,
true, true,
@ -895,12 +895,12 @@ mod unit_tests {
vec![ vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256}
] ]
}"#, }"#,
true, true,
@ -909,12 +909,12 @@ mod unit_tests {
vec![ vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true}
] ]
}"#, }"#,
false, false,
@ -923,12 +923,12 @@ mod unit_tests {
vec![ vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true}
], ],
"iommu": true "iommu": true
}"#, }"#,
@ -938,23 +938,23 @@ mod unit_tests {
vec![ vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=off", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=off",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": false} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": false}
] ]
}"#, }"#,
true, true,
), ),
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "shared=true", "--net", "mac=12:34:56:78:90:ab,vhost_user=true,socket=/tmp/socket"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "shared=true", "--net", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,vhost_user=true,socket=/tmp/socket"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 }, "memory" : { "shared": true, "size": 536870912 },
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "vhost_user": true, "vhost_socket": "/tmp/socket"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "vhost_user": true, "vhost_socket": "/tmp/socket"}
] ]
}"#, }"#,
true, true,

View File

@ -16,7 +16,7 @@ extern crate vmm;
use epoll; use epoll;
use libc::{self, EAGAIN, EFD_NONBLOCK}; use libc::{self, EAGAIN, EFD_NONBLOCK};
use log::*; use log::*;
use net_util::Tap; use net_util::{MacAddr, Tap};
use std::fmt; use std::fmt;
use std::io::Read; use std::io::Read;
use std::io::{self}; use std::io::{self};
@ -221,13 +221,20 @@ pub struct VhostUserNetBackend {
impl VhostUserNetBackend { impl VhostUserNetBackend {
fn new( fn new(
ip_addr: Ipv4Addr, ip_addr: Ipv4Addr,
host_mac: MacAddr,
netmask: Ipv4Addr, netmask: Ipv4Addr,
num_queues: usize, num_queues: usize,
queue_size: u16, queue_size: u16,
ifname: Option<&str>, ifname: Option<&str>,
) -> Result<Self> { ) -> Result<Self> {
let mut taps = open_tap(ifname, Some(ip_addr), Some(netmask), num_queues / 2) let mut taps = open_tap(
.map_err(Error::OpenTap)?; ifname,
Some(ip_addr),
Some(netmask),
Some(host_mac),
num_queues / 2,
)
.map_err(Error::OpenTap)?;
let mut queues_per_thread = Vec::new(); let mut queues_per_thread = Vec::new();
let mut threads = Vec::new(); let mut threads = Vec::new();
@ -351,6 +358,7 @@ impl VhostUserBackend for VhostUserNetBackend {
pub struct VhostUserNetBackendConfig { pub struct VhostUserNetBackendConfig {
pub ip: Ipv4Addr, pub ip: Ipv4Addr,
pub host_mac: MacAddr,
pub mask: Ipv4Addr, pub mask: Ipv4Addr,
pub socket: String, pub socket: String,
pub num_queues: usize, pub num_queues: usize,
@ -365,6 +373,7 @@ impl VhostUserNetBackendConfig {
parser parser
.add("tap") .add("tap")
.add("ip") .add("ip")
.add("host_mac")
.add("mask") .add("mask")
.add("queue_size") .add("queue_size")
.add("num_queues") .add("num_queues")
@ -377,6 +386,10 @@ impl VhostUserNetBackendConfig {
.convert("ip") .convert("ip")
.map_err(Error::FailedConfigParse)? .map_err(Error::FailedConfigParse)?
.unwrap_or_else(|| Ipv4Addr::new(192, 168, 100, 1)); .unwrap_or_else(|| Ipv4Addr::new(192, 168, 100, 1));
let host_mac = parser
.convert("host_mac")
.map_err(Error::FailedConfigParse)?
.unwrap_or_else(MacAddr::local_random);
let mask = parser let mask = parser
.convert("mask") .convert("mask")
.map_err(Error::FailedConfigParse)? .map_err(Error::FailedConfigParse)?
@ -393,6 +406,7 @@ impl VhostUserNetBackendConfig {
Ok(VhostUserNetBackendConfig { Ok(VhostUserNetBackendConfig {
ip, ip,
host_mac,
mask, mask,
socket, socket,
num_queues, num_queues,
@ -420,6 +434,7 @@ pub fn start_net_backend(backend_command: &str) {
let net_backend = Arc::new(RwLock::new( let net_backend = Arc::new(RwLock::new(
VhostUserNetBackend::new( VhostUserNetBackend::new(
backend_config.ip, backend_config.ip,
backend_config.host_mac,
backend_config.mask, backend_config.mask,
backend_config.num_queues, backend_config.num_queues,
backend_config.queue_size, backend_config.queue_size,

View File

@ -392,11 +392,13 @@ 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>,
iommu: bool, iommu: bool,
num_queues: usize, num_queues: usize,
queue_size: u16, queue_size: u16,
) -> Result<Self> { ) -> Result<Self> {
let taps = open_tap(if_name, ip_addr, netmask, num_queues / 2).map_err(Error::OpenTap)?; let taps = open_tap(if_name, ip_addr, netmask, host_mac, num_queues / 2)
.map_err(Error::OpenTap)?;
Self::new_with_tap(id, taps, guest_mac, iommu, num_queues, queue_size) Self::new_with_tap(id, taps, guest_mac, iommu, num_queues, queue_size)
} }

View File

@ -119,6 +119,8 @@ pub enum Error {
TapSetIp(TapError), TapSetIp(TapError),
/// Setting tap netmask failed. /// Setting tap netmask failed.
TapSetNetmask(TapError), TapSetNetmask(TapError),
/// Setting MAC address failed
TapSetMac(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.
@ -531,6 +533,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>,
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();
@ -558,6 +561,9 @@ pub fn open_tap(
if let Some(mask) = netmask { if let Some(mask) = netmask {
tap.set_netmask(mask).map_err(Error::TapSetNetmask)?; tap.set_netmask(mask).map_err(Error::TapSetNetmask)?;
} }
if let Some(mac) = host_mac {
tap.set_mac_addr(mac).map_err(Error::TapSetMac)?
}
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

@ -701,6 +701,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")]
pub host_mac: MacAddr,
#[serde(default)] #[serde(default)]
pub iommu: bool, pub iommu: bool,
#[serde(default = "default_netconfig_num_queues")] #[serde(default = "default_netconfig_num_queues")]
@ -745,6 +747,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(),
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(),
@ -769,6 +772,7 @@ impl NetConfig {
.add("ip") .add("ip")
.add("mask") .add("mask")
.add("mac") .add("mac")
.add("host_mac")
.add("iommu") .add("iommu")
.add("queue_size") .add("queue_size")
.add("num_queues") .add("num_queues")
@ -790,6 +794,10 @@ 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
.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)?
@ -816,6 +824,7 @@ impl NetConfig {
ip, ip,
mask, mask,
mac, mac,
host_mac,
iommu, iommu,
num_queues, num_queues,
queue_size, queue_size,
@ -1641,17 +1650,19 @@ mod tests {
fn test_net_parsing() -> Result<()> { fn test_net_parsing() -> Result<()> {
// mac address is random // mac address is random
assert_eq!( assert_eq!(
NetConfig::parse("mac=de:ad:be:ef:12:34")?, 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(),
..Default::default() ..Default::default()
} }
); );
assert_eq!( assert_eq!(
NetConfig::parse("mac=de:ad:be:ef:12:34,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(),
id: Some("mynet0".to_owned()), id: Some("mynet0".to_owned()),
..Default::default() ..Default::default()
} }
@ -1659,10 +1670,11 @@ mod tests {
assert_eq!( assert_eq!(
NetConfig::parse( NetConfig::parse(
"mac=de:ad:be:ef:12:34,tap=tap0,ip=192.168.100.1,mask=255.255.255.128" "mac=de:ad:be:ef:12:34,host_mac=12:34:de:ad:be:ef,tap=tap0,ip=192.168.100.1,mask=255.255.255.128"
)?, )?,
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(),
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(),
@ -1671,9 +1683,10 @@ mod tests {
); );
assert_eq!( assert_eq!(
NetConfig::parse("mac=de:ad:be:ef:12:34,vhost_user=true,socket=/tmp/socket")?, NetConfig::parse("mac=de:ad:be:ef:12:34,host_mac=12:34:de:ad:be:ef,vhost_user=true,socket=/tmp/socket")?,
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(),
vhost_user: true, vhost_user: true,
vhost_socket: Some("/tmp/socket".to_owned()), vhost_socket: Some("/tmp/socket".to_owned()),
..Default::default() ..Default::default()
@ -1681,9 +1694,10 @@ mod tests {
); );
assert_eq!( assert_eq!(
NetConfig::parse("mac=de:ad:be:ef:12:34,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(),
num_queues: 4, num_queues: 4,
queue_size: 1024, queue_size: 1024,
iommu: true, iommu: true,

View File

@ -1463,8 +1463,13 @@ impl DeviceManager {
.args(&[ .args(&[
"--net-backend", "--net-backend",
&format!( &format!(
"ip={},mask={},socket={},num_queues={},queue_size={}", "ip={},mask={},socket={},num_queues={},queue_size={},host_mac={}",
net_cfg.ip, net_cfg.mask, &sock, net_cfg.num_queues, net_cfg.queue_size net_cfg.ip,
net_cfg.mask,
&sock,
net_cfg.num_queues,
net_cfg.queue_size,
net_cfg.host_mac
), ),
]) ])
.spawn() .spawn()
@ -1529,6 +1534,7 @@ impl DeviceManager {
None, None,
None, None,
Some(net_cfg.mac), Some(net_cfg.mac),
Some(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,
@ -1543,6 +1549,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),
net_cfg.iommu, net_cfg.iommu,
net_cfg.num_queues, net_cfg.num_queues,
net_cfg.queue_size, net_cfg.queue_size,