diff --git a/net_util/Cargo.toml b/net_util/Cargo.toml index 66a6466495..24eb37869f 100644 --- a/net_util/Cargo.toml +++ b/net_util/Cargo.toml @@ -9,3 +9,4 @@ libc = "*" data_model = { path = "../data_model" } net_sys = { path = "../net_sys" } base = { path = "../base" } +cros_async = { path = "../cros_async" } diff --git a/net_util/src/lib.rs b/net_util/src/lib.rs index 5a08f65d4c..b64feb2586 100644 --- a/net_util/src/lib.rs +++ b/net_util/src/lib.rs @@ -20,6 +20,7 @@ use base::{ ioctl_with_mut_ref, ioctl_with_ref, ioctl_with_val, volatile_impl, AsRawDescriptor, FromRawDescriptor, IoctlNr, RawDescriptor, }; +use cros_async::IntoAsync; #[derive(Debug)] pub enum Error { @@ -29,6 +30,8 @@ pub enum Error { OpenTun(SysError), /// Unable to create tap interface. CreateTap(SysError), + /// Unable to clone tap interface. + CloneTap(SysError), /// ioctl failed. IoctlError(SysError), } @@ -42,6 +45,7 @@ impl Display for Error { CreateSocket(e) => write!(f, "failed to create a socket: {}", e), OpenTun(e) => write!(f, "failed to open /dev/net/tun: {}", e), CreateTap(e) => write!(f, "failed to create tap interface: {}", e), + CloneTap(e) => write!(f, "failed to clone tap interface: {}", e), IoctlError(e) => write!(f, "ioctl failed: {}", e), } } @@ -53,6 +57,7 @@ impl Error { Error::CreateSocket(e) => e, Error::OpenTun(e) => e, Error::CreateTap(e) => e, + Error::CloneTap(e) => e, Error::IoctlError(e) => e, } } @@ -227,6 +232,18 @@ impl Tap { if_flags: unsafe { ifreq.ifr_ifru.ifru_flags }, }) } + + pub fn try_clone(&self) -> Result { + self.tap_file + .try_clone() + .map(|tap_file| Tap { + tap_file, + if_name: self.if_name, + if_flags: self.if_flags, + }) + .map_err(SysError::from) + .map_err(Error::CloneTap) + } } pub trait TapT: FileReadWriteVolatile + Read + Write + AsRawDescriptor + Send + Sized { @@ -527,6 +544,8 @@ impl AsRawDescriptor for Tap { } } +impl IntoAsync for Tap {} + volatile_impl!(Tap); pub mod fakes {