Link TAP interface to VM
Bug: 340376951
Test: adb shell /apex/com.android.virt/bin/vm run-microdroid
--network-supported
Change-Id: I1937d9bd7393942541aa8c8e545a2aa7704de501
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index aeee6f7..d173b34 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -607,13 +607,20 @@
};
// Create TAP network interface if the VM supports network.
- let _tap_fd = if cfg!(network) && config.networkSupported {
+ let tap = if cfg!(network) && config.networkSupported {
if *is_protected {
return Err(anyhow!("Network feature is not supported for pVM yet"))
.with_log()
.or_binder_exception(ExceptionCode::UNSUPPORTED_OPERATION)?;
}
- Some(GLOBAL_SERVICE.createTapInterface(&get_this_pid().to_string())?)
+ Some(File::from(
+ GLOBAL_SERVICE
+ .createTapInterface(&get_this_pid().to_string())?
+ .as_ref()
+ .try_clone()
+ .context("Failed to get TAP interface from ParcelFileDescriptor")
+ .or_binder_exception(ExceptionCode::BAD_PARCELABLE)?,
+ ))
} else {
None
};
@@ -646,6 +653,7 @@
display_config,
input_device_options,
hugepages: config.hugePages,
+ tap,
};
let instance = Arc::new(
VmInstance::new(
diff --git a/virtualizationmanager/src/crosvm.rs b/virtualizationmanager/src/crosvm.rs
index d48ef7b..f73a977 100644
--- a/virtualizationmanager/src/crosvm.rs
+++ b/virtualizationmanager/src/crosvm.rs
@@ -122,6 +122,7 @@
pub display_config: Option<DisplayConfig>,
pub input_device_options: Vec<InputDeviceOption>,
pub hugepages: bool,
+ pub tap: Option<File>,
}
#[derive(Debug)]
@@ -979,7 +980,7 @@
}
if cfg!(paravirtualized_devices) {
- // TODO(b/325929096): Need to set up network from the config
+ // TODO(b/340376951): Remove this after tap in CrosvmConfig is connected to tethering.
if rustutils::system_properties::read_bool("ro.crosvm.network.setup.done", false)
.unwrap_or(false)
{
@@ -987,6 +988,14 @@
}
}
+ if cfg!(network) {
+ if let Some(tap) = &config.tap {
+ let tap_fd = tap.as_raw_fd();
+ preserved_fds.push(tap_fd);
+ command.arg("--net").arg(format!("tap-fd={}", tap_fd));
+ }
+ }
+
if cfg!(paravirtualized_devices) {
for input_device_option in config.input_device_options.iter() {
command.arg("--input");
diff --git a/virtualizationservice/vmnic/src/aidl.rs b/virtualizationservice/vmnic/src/aidl.rs
index ef1fda9..a206c25 100644
--- a/virtualizationservice/vmnic/src/aidl.rs
+++ b/virtualizationservice/vmnic/src/aidl.rs
@@ -17,7 +17,7 @@
use anyhow::{anyhow, Context, Result};
use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::IVmnic::IVmnic;
use binder::{self, Interface, IntoBinderResult, ParcelFileDescriptor};
-use libc::{c_char, c_int, c_short, ifreq, IFF_NO_PI, IFF_TAP, IFF_UP, IFNAMSIZ};
+use libc::{c_char, c_int, c_short, ifreq, IFF_NO_PI, IFF_TAP, IFF_UP, IFF_VNET_HDR, IFNAMSIZ};
use log::info;
use nix::{ioctl_write_int_bad, ioctl_write_ptr_bad};
use nix::sys::ioctl::ioctl_num_type;
@@ -47,7 +47,7 @@
fn create_tap_interface(fd: RawFd, ifname: &[c_char]) -> Result<()> {
// SAFETY: All-zero is a valid value for the ifreq type.
let mut ifr: ifreq = unsafe { std::mem::zeroed() };
- ifr.ifr_ifru.ifru_flags = (IFF_TAP | IFF_NO_PI) as c_short;
+ ifr.ifr_ifru.ifru_flags = (IFF_TAP | IFF_NO_PI | IFF_VNET_HDR) as c_short;
ifr.ifr_name[..ifname.len()].copy_from_slice(ifname);
// SAFETY: `ioctl` is copied into the kernel. It modifies the state in the kernel, not the
// state of this process in any way.