summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJorge E. Moreira <jemoreira@google.com>2019-02-12 16:43:05 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-02-14 05:27:29 -0800
commitb795280ddcd9d290d89ff0e284bc12ae91640baf (patch)
tree1e239b71a3ac253b91410c87543c396cbfa950fb /src
parent348ccf1102895acf5a064d388ab8249c575ccafb (diff)
downloadcrosvm-b795280ddcd9d290d89ff0e284bc12ae91640baf.tar
crosvm-b795280ddcd9d290d89ff0e284bc12ae91640baf.tar.gz
crosvm-b795280ddcd9d290d89ff0e284bc12ae91640baf.tar.bz2
crosvm-b795280ddcd9d290d89ff0e284bc12ae91640baf.tar.lz
crosvm-b795280ddcd9d290d89ff0e284bc12ae91640baf.tar.xz
crosvm-b795280ddcd9d290d89ff0e284bc12ae91640baf.tar.zst
crosvm-b795280ddcd9d290d89ff0e284bc12ae91640baf.zip
Add support for multiple network interfaces
Allow --tap-fd to be given mutliple times, a different virtual network
card will be added each time the flag is given.
Additionally, --tap-fd is no longer mutually exclusive with --host-ip,
etc.

Bug=chromium:931470
Test=booted cuttlefish device with multiple network cards

Change-Id: I4108f97c7f4b19db12fcb3c533088a04a58e56db
Reviewed-on: https://chromium-review.googlesource.com/1469222
Commit-Ready: Jorge Moreira Broche <jemoreira@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Tested-by: Jorge Moreira Broche <jemoreira@google.com>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'src')
-rw-r--r--src/linux.rs6
-rw-r--r--src/main.rs38
-rw-r--r--src/plugin/mod.rs17
-rw-r--r--src/plugin/process.rs4
4 files changed, 24 insertions, 41 deletions
diff --git a/src/linux.rs b/src/linux.rs
index b81bc71..1dbd8fd 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -432,7 +432,7 @@ fn create_virtio_devs(
     });
 
     // We checked above that if the IP is defined, then the netmask is, too.
-    if let Some(tap_fd) = cfg.tap_fd {
+    for tap_fd in cfg.tap_fd {
         // Safe because we ensure that we get a unique handle to the fd.
         let tap = unsafe {
             Tap::from_raw_fd(validate_raw_fd(tap_fd).map_err(Error::ValidateRawFd)?)
@@ -449,7 +449,9 @@ fn create_virtio_devs(
         };
 
         devs.push(VirtioDeviceStub { dev: net_box, jail });
-    } else if let Some(host_ip) = cfg.host_ip {
+    }
+
+    if let Some(host_ip) = cfg.host_ip {
         if let Some(netmask) = cfg.netmask {
             if let Some(mac_address) = cfg.mac_address {
                 let net_box: Box<devices::virtio::VirtioDevice> = if cfg.vhost_net {
diff --git a/src/main.rs b/src/main.rs
index 16dcf10..3e3afef 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -108,7 +108,7 @@ pub struct Config {
     netmask: Option<net::Ipv4Addr>,
     mac_address: Option<net_util::MacAddress>,
     vhost_net: bool,
-    tap_fd: Option<RawFd>,
+    tap_fd: Vec<RawFd>,
     cid: Option<u64>,
     wayland_socket_path: Option<PathBuf>,
     wayland_dmabuf: bool,
@@ -143,7 +143,7 @@ impl Default for Config {
             netmask: None,
             mac_address: None,
             vhost_net: false,
-            tap_fd: None,
+            tap_fd: Vec::new(),
             cid: None,
             gpu: false,
             wayland_socket_path: None,
@@ -505,21 +505,15 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument::
         }
         "vhost-net" => cfg.vhost_net = true,
         "tap-fd" => {
-            if cfg.tap_fd.is_some() {
-                return Err(argument::Error::TooManyArguments(
-                    "`tap-fd` alread given".to_owned(),
-                ));
-            }
-            cfg.tap_fd =
-                Some(
-                    value
-                        .unwrap()
-                        .parse()
-                        .map_err(|_| argument::Error::InvalidValue {
-                            value: value.unwrap().to_owned(),
-                            expected: "this value for `tap-fd` must be an unsigned integer",
-                        })?,
-                );
+            cfg.tap_fd.push(
+                value
+                    .unwrap()
+                    .parse()
+                    .map_err(|_| argument::Error::InvalidValue {
+                        value: value.unwrap().to_owned(),
+                        expected: "this value for `tap-fd` must be an unsigned integer",
+                    })?,
+            );
         }
         "gpu" => {
             cfg.gpu = true;
@@ -632,7 +626,7 @@ fn run_vm(args: std::env::Args) -> std::result::Result<(), ()> {
           Argument::flag("vhost-net", "Use vhost for networking."),
           Argument::value("tap-fd",
                           "fd",
-                          "File descriptor for configured tap device.  Mutually exclusive with `host_ip`, `netmask`, and `mac`."),
+                          "File descriptor for configured tap device. A different virtual network card will be added each time this argument is given."),
           #[cfg(feature = "gpu")]
           Argument::flag("gpu", "(EXPERIMENTAL) enable virtio-gpu device"),
           Argument::value("evdev", "PATH", "Path to an event device node. The device will be grabbed (unusable from the host) and made available to the guest with the same configuration it shows on the host"),
@@ -673,14 +667,6 @@ fn run_vm(args: std::env::Args) -> std::result::Result<(), ()> {
                 "`plugin-root` requires `plugin`".to_owned(),
             ));
         }
-        if cfg.tap_fd.is_some()
-            && (cfg.host_ip.is_some() || cfg.netmask.is_some() || cfg.mac_address.is_some())
-        {
-            return Err(argument::Error::TooManyArguments(
-                "`tap_fd` and any of `host_ip`, `netmask`, or `mac` are mutually exclusive"
-                    .to_owned(),
-            ));
-        }
         Ok(())
     });
 
diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs
index 7163d7a..32ea4bb 100644
--- a/src/plugin/mod.rs
+++ b/src/plugin/mod.rs
@@ -506,7 +506,7 @@ pub fn run_config(cfg: Config) -> Result<()> {
         None
     };
 
-    let mut tap_opt: Option<Tap> = None;
+    let mut tap_interfaces: Vec<Tap> = Vec::new();
     if let Some(host_ip) = cfg.host_ip {
         if let Some(netmask) = cfg.netmask {
             if let Some(mac_address) = cfg.mac_address {
@@ -517,17 +517,17 @@ pub fn run_config(cfg: Config) -> Result<()> {
                     .map_err(Error::TapSetMacAddress)?;
 
                 tap.enable().map_err(Error::TapEnable)?;
-                tap_opt = Some(tap);
+                tap_interfaces.push(tap);
             }
         }
     }
-    if let Some(tap_fd) = cfg.tap_fd {
+    for tap_fd in cfg.tap_fd {
         // Safe because we ensure that we get a unique handle to the fd.
         let tap = unsafe {
             Tap::from_raw_fd(validate_raw_fd(tap_fd).map_err(Error::ValidateTapFd)?)
                 .map_err(Error::CreateTapFd)?
         };
-        tap_opt = Some(tap);
+        tap_interfaces.push(tap);
     }
 
     let plugin_args: Vec<&str> = cfg.params.iter().map(|s| &s[..]).collect();
@@ -650,13 +650,8 @@ pub fn run_config(cfg: Config) -> Result<()> {
                     }
                 }
                 Token::Plugin { index } => {
-                    match plugin.handle_socket(
-                        index,
-                        &kvm,
-                        &mut vm,
-                        &vcpu_handles,
-                        tap_opt.as_ref(),
-                    ) {
+                    match plugin.handle_socket(index, &kvm, &mut vm, &vcpu_handles, &tap_interfaces)
+                    {
                         Ok(_) => {}
                         // A HUP is an expected event for a socket, so don't bother warning about
                         // it.
diff --git a/src/plugin/process.rs b/src/plugin/process.rs
index f3045fa..2f3560d 100644
--- a/src/plugin/process.rs
+++ b/src/plugin/process.rs
@@ -457,7 +457,7 @@ impl Process {
         kvm: &Kvm,
         vm: &mut Vm,
         vcpu_handles: &[JoinHandle<()>],
-        tap: Option<&Tap>,
+        taps: &Vec<Tap>,
     ) -> Result<()> {
         let (msg_size, request_file) = self.request_sockets[index]
             .recv_with_fd(&mut self.request_buffer)
@@ -603,7 +603,7 @@ impl Process {
                 Ok(())
             }
         } else if request.has_get_net_config() {
-            match tap {
+            match taps.first() {
                 Some(tap) => {
                     match Self::handle_get_net_config(tap, response.mut_get_net_config()) {
                         Ok(_) => {