From 929d70bc7f9c22ce2aedaa1ab53cf4e0151e3f25 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Fri, 5 Jun 2020 11:56:57 +0100 Subject: [PATCH] net_util: Only try and enable the TAP device if it not already enabled This allows an existing TAP interface to be used without needing CAP_NET_ADMIN permissions on the Cloud Hypervisor binary as the ioctl to bring up the interface is avoided. Signed-off-by: Rob Bradford --- net_util/src/tap.rs | 17 +++++++++++++++++ vmm/src/seccomp_filters.rs | 2 ++ 2 files changed, 19 insertions(+) diff --git a/net_util/src/tap.rs b/net_util/src/tap.rs index 6a5ac70d4..2f99a82ca 100644 --- a/net_util/src/tap.rs +++ b/net_util/src/tap.rs @@ -249,9 +249,26 @@ impl Tap { let mut ifreq = self.get_ifreq(); + #[allow(clippy::cast_lossless)] + let ret = + unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCGIFFLAGS as c_ulong, &ifreq) }; + if ret < 0 { + return Err(Error::IoctlError(IoError::last_os_error())); + } + + // If TAP device is already up don't try and enable it + let ifru_flags = unsafe { ifreq.ifr_ifru.ifru_flags.as_ref() }; + if ifru_flags + & (net_gen::net_device_flags_IFF_UP | net_gen::net_device_flags_IFF_RUNNING) as i16 + == (net_gen::net_device_flags_IFF_UP | net_gen::net_device_flags_IFF_RUNNING) as i16 + { + return Ok(()); + } + // We only access one field of the ifru union, hence this is safe. unsafe { let ifru_flags = ifreq.ifr_ifru.ifru_flags.as_mut(); + *ifru_flags = (net_gen::net_device_flags_IFF_UP | net_gen::net_device_flags_IFF_RUNNING) as i16; } diff --git a/vmm/src/seccomp_filters.rs b/vmm/src/seccomp_filters.rs index 0ed7b3f18..6494f88f5 100644 --- a/vmm/src/seccomp_filters.rs +++ b/vmm/src/seccomp_filters.rs @@ -87,6 +87,7 @@ const TUNSETVNETHDRSZ: u64 = 0x4004_54d8; const TUNGETFEATURES: u64 = 0x8004_54cf; // See include/uapi/linux/sockios.h in the kernel code. +const SIOCGIFFLAGS: u64 = 0x8913; const SIOCGIFHWADDR: u64 = 0x8927; const SIOCSIFFLAGS: u64 = 0x8914; const SIOCSIFADDR: u64 = 0x8916; @@ -149,6 +150,7 @@ fn create_vmm_ioctl_seccomp_rule() -> Result, Error> { and![Cond::new(1, ArgLen::DWORD, Eq, KVM_SET_USER_MEMORY_REGION,)?], and![Cond::new(1, ArgLen::DWORD, Eq, KVM_SET_XSAVE,)?], and![Cond::new(1, ArgLen::DWORD, Eq, KVM_SET_XCRS,)?], + and![Cond::new(1, ArgLen::DWORD, Eq, SIOCGIFFLAGS)?], and![Cond::new(1, ArgLen::DWORD, Eq, SIOCGIFHWADDR)?], and![Cond::new(1, ArgLen::DWORD, Eq, SIOCSIFADDR)?], and![Cond::new(1, ArgLen::DWORD, Eq, SIOCSIFFLAGS)?],