summary refs log tree commit diff
path: root/src/main.rs
diff options
context:
space:
mode:
authorStephen Barber <smbarber@chromium.org>2017-08-07 17:13:38 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-08-16 07:48:27 -0700
commit5e77e88062c65463a98d1c58ba9646e99b47d80f (patch)
tree33536d9f87ee7b62c34717074ebf1bc7d49d7b86 /src/main.rs
parentd527d85da64ff265a8091fc9129244e02f994f0a (diff)
downloadcrosvm-5e77e88062c65463a98d1c58ba9646e99b47d80f.tar
crosvm-5e77e88062c65463a98d1c58ba9646e99b47d80f.tar.gz
crosvm-5e77e88062c65463a98d1c58ba9646e99b47d80f.tar.bz2
crosvm-5e77e88062c65463a98d1c58ba9646e99b47d80f.tar.lz
crosvm-5e77e88062c65463a98d1c58ba9646e99b47d80f.tar.xz
crosvm-5e77e88062c65463a98d1c58ba9646e99b47d80f.tar.zst
crosvm-5e77e88062c65463a98d1c58ba9646e99b47d80f.zip
crosvm: add pure virtio net device
While vhost_net can provide better performance than a userspace
virtio device, it also requires a kernel module to function. This
also prevents jailing the virtio device, since virtqueue operations
(which necessarily touch guest memory) will be running directly
in the kernel.

Add a userspace virtio net device that can be jailed and works
without vhost support in the kernel.

BUG=chromium:703920
TEST=networking works

Change-Id: I468114b48abd8e30e967ff16329a5dce6a75018f
Signed-off-by: Stephen Barber <smbarber@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/604937
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/main.rs b/src/main.rs
index 6449792..45138f9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -52,6 +52,7 @@ enum Error {
     BlockDeviceNew(sys_util::Error),
     BlockDeviceRootSetup(sys_util::Error),
     VhostNetDeviceNew(hw::virtio::VhostNetError),
+    NetDeviceNew(hw::virtio::NetError),
     NetDeviceRootSetup(sys_util::Error),
     MacAddressNeedsNetConfig,
     NetMissingConfig,
@@ -104,6 +105,7 @@ impl fmt::Display for Error {
             }
             &Error::RegisterBlock(ref e) => write!(f, "error registering block device: {:?}", e),
             &Error::VhostNetDeviceNew(ref e) => write!(f, "failed to set up vhost networking: {:?}", e),
+            &Error::NetDeviceNew(ref e) => write!(f, "failed to set up virtio networking: {:?}", e),
             &Error::NetDeviceRootSetup(ref e) => {
                 write!(f, "failed to create root directory for a net device: {:?}", e)
             }
@@ -148,6 +150,7 @@ struct Config<'a> {
     host_ip: Option<net::Ipv4Addr>,
     netmask: Option<net::Ipv4Addr>,
     mac_address: Option<String>,
+    vhost_net: bool,
     socket_path: Option<String>,
     multiprocess: bool,
     warn_unknown_ports: bool,
@@ -286,12 +289,24 @@ fn run_config(cfg: Config) -> Result<()> {
         .map_err(Error::NetDeviceRootSetup)?;
     if let Some(host_ip) = cfg.host_ip {
         if let Some(netmask) = cfg.netmask {
-            let net_box = Box::new(hw::virtio::VhostNet::new(host_ip, netmask, &guest_mem)
-                                   .map_err(|e| Error::VhostNetDeviceNew(e))?);
+            let net_box: Box<hw::virtio::VirtioDevice> = if cfg.vhost_net {
+                Box::new(hw::virtio::VhostNet::new(host_ip, netmask, &guest_mem)
+                                   .map_err(|e| Error::VhostNetDeviceNew(e))?)
+            } else {
+                Box::new(hw::virtio::Net::new(host_ip, netmask)
+                                   .map_err(|e| Error::NetDeviceNew(e))?)
+            };
+
             let jail = if cfg.multiprocess {
                 let net_root_path = net_root.as_path().unwrap(); // Won't fail if new succeeded.
 
-                Some(create_base_minijail(net_root_path, Path::new("vhost_net_device.policy"))?)
+                let policy_path = if cfg.vhost_net {
+                    Path::new("vhost_net_device.policy")
+                } else {
+                    Path::new("net_device.policy")
+                };
+
+                Some(create_base_minijail(net_root_path, policy_path)?)
             }
             else {
                 None
@@ -683,6 +698,9 @@ fn main() {
                                  .long("mac")
                                  .value_name("MAC")
                                  .help("mac address for VM"))
+                        .arg(Arg::with_name("vhost_net")
+                                 .long("vhost_net")
+                                 .help("use vhost_net for networking"))
                         .arg(Arg::with_name("socket")
                                  .short("s")
                                  .long("socket")
@@ -740,6 +758,7 @@ fn main() {
                 host_ip: matches.value_of("host_ip").and_then(|v| v.parse().ok()),
                 netmask: matches.value_of("netmask").and_then(|v| v.parse().ok()),
                 mac_address: matches.value_of("mac").map(|s| s.to_string()),
+                vhost_net: matches.is_present("vhost_net"),
                 socket_path: matches.value_of("socket").map(|s| s.to_string()),
                 warn_unknown_ports: matches.is_present("warn-unknown-ports"),
             };