Skip to content

Commit f6e18b4

Browse files
committed
net_tap: change TapHandle from device name to pre-opened fd
TapHandle in net_backend_resources carried a device name string and the resolver opened the TAP device. Change it to carry a pre-opened OwnedFd so the opener (openvmm_entry or a test harness) controls namespace and permission details. This resolves a long-standing TODO and enables fd passing from Kata and similar environments. Also tighten both TapHandle and net_tap from cfg(unix) to cfg(target_os = "linux") since TAP uses Linux-specific /dev/net/tun ioctls.
1 parent 23d961a commit f6e18b4

File tree

8 files changed

+38
-15
lines changed

8 files changed

+38
-15
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5356,6 +5356,7 @@ dependencies = [
53565356
"mesh_rpc",
53575357
"mesh_worker",
53585358
"net_backend_resources",
5359+
"net_tap",
53595360
"netvsp_resources",
53605361
"nvme_resources",
53615362
"openssl",

openvmm/openvmm_entry/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ tracing.workspace = true
105105
tracing-subscriber = { workspace = true, features = ["env-filter"] }
106106
unicycle.workspace = true
107107

108+
[target.'cfg(target_os = "linux")'.dependencies]
109+
net_tap.workspace = true
110+
108111
[target.'cfg(windows)'.dependencies]
109112
vmswitch.workspace = true
110113
virt_whp.workspace = true

openvmm/openvmm_entry/src/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,17 @@ fn parse_endpoint(
18501850
}
18511851
}
18521852
EndpointConfigCli::Tap { name } => {
1853-
net_backend_resources::tap::TapHandle { name: name.clone() }.into_resource()
1853+
#[cfg(target_os = "linux")]
1854+
{
1855+
let fd = net_tap::tap::open_tap(name).context("failed to open TAP device")?;
1856+
net_backend_resources::tap::TapHandle { fd }.into_resource()
1857+
}
1858+
1859+
#[cfg(not(target_os = "linux"))]
1860+
{
1861+
let _ = name;
1862+
bail!("TAP backend is only supported on Linux")
1863+
}
18541864
}
18551865
};
18561866

openvmm/openvmm_entry/src/ttrpc/mod.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
66
#![cfg(any(feature = "ttrpc", feature = "grpc"))]
77

8-
use self::vmservice::nic_config::Backend;
98
use crate::serial_io::bind_serial;
109
use anyhow::Context;
1110
use anyhow::anyhow;
@@ -704,9 +703,21 @@ impl VmService {
704703
}
705704
}
706705

706+
// On platforms without NIC backends (e.g., macOS), every match arm diverges.
707+
#[cfg_attr(
708+
not(any(windows, target_os = "linux")),
709+
expect(
710+
unreachable_code,
711+
unused_variables,
712+
reason = "no NIC backends available on this platform"
713+
)
714+
)]
707715
fn parse_nic_config(
708716
nic: vmservice::NicConfig,
709717
) -> anyhow::Result<(DeviceVtl, Resource<VmbusDeviceHandleKind>)> {
718+
#[cfg(any(windows, target_os = "linux"))]
719+
use self::vmservice::nic_config::Backend;
720+
710721
let endpoint = match nic.backend.context("missing backend")? {
711722
#[cfg(windows)]
712723
Backend::LegacyPortId(port_id) => net_backend_resources::dio::WindowsDirectIoHandle {
@@ -724,9 +735,10 @@ fn parse_nic_config(
724735
},
725736
}
726737
.into_resource(),
727-
#[cfg(unix)]
738+
#[cfg(target_os = "linux")]
728739
Backend::Tap(tap) => {
729-
net_backend_resources::tap::TapHandle { name: tap.name }.into_resource()
740+
let fd = net_tap::tap::open_tap(&tap.name).context("failed to open TAP device")?;
741+
net_backend_resources::tap::TapHandle { fd }.into_resource()
730742
}
731743
_ => anyhow::bail!("unsupported backend"),
732744
};

vm/devices/net/net_backend_resources/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub mod dio {
7272
}
7373

7474
/// Linux TAP backend.
75+
#[cfg(target_os = "linux")]
7576
pub mod tap {
7677
use mesh::MeshPayload;
7778
use vm_resource::ResourceId;
@@ -80,10 +81,9 @@ pub mod tap {
8081
/// A handle to a TAP device.
8182
#[derive(MeshPayload)]
8283
pub struct TapHandle {
83-
/// The name of the TAP device.
84-
///
85-
/// FUTURE: change this to a pre-opened `File`.
86-
pub name: String,
84+
/// A pre-opened TAP file descriptor, configured with
85+
/// `IFF_TAP | IFF_NO_PI | IFF_VNET_HDR`.
86+
pub fd: std::os::fd::OwnedFd,
8787
}
8888

8989
impl ResourceId<NetEndpointHandleKind> for TapHandle {

vm/devices/net/net_tap/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ name = "net_tap"
66
edition.workspace = true
77
rust-version.workspace = true
88

9-
[target.'cfg(unix)'.dependencies]
9+
[target.'cfg(target_os = "linux")'.dependencies]
1010
net_backend.workspace = true
1111
net_backend_resources.workspace = true
1212
linux_net_bindings.workspace = true
@@ -27,7 +27,7 @@ thiserror.workspace = true
2727
tracing.workspace = true
2828
zerocopy.workspace = true
2929

30-
[target.'cfg(unix)'.dev-dependencies]
30+
[target.'cfg(target_os = "linux")'.dev-dependencies]
3131
guestmem.workspace = true
3232
libtest-mimic.workspace = true
3333
net_backend.workspace = true

vm/devices/net/net_tap/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
//! A TAP interface based endpoint.
55
6-
#![cfg(unix)]
6+
#![cfg(target_os = "linux")]
77
#![expect(missing_docs)]
88

99
pub mod resolver;

vm/devices/net/net_tap/src/resolver.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ impl ResolveResource<NetEndpointHandleKind, TapHandle> for TapResolver {
2626
resource: TapHandle,
2727
_input: ResolveEndpointParams,
2828
) -> Result<Self::Output, Self::Error> {
29-
// TODO: accept a pre-opened fd from the resource handle instead of
30-
// opening by name here, to support fd passing from Kata and similar.
31-
let fd = tap::open_tap(&resource.name)?;
32-
let tap = tap::Tap::new(fd)?;
29+
let tap = tap::Tap::new(resource.fd)?;
3330

3431
Ok(TapEndpoint::new(tap)?.into())
3532
}

0 commit comments

Comments
 (0)