1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/openeuler-stratovirt

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
tap.rs 4.8 КБ
Копировать Редактировать Исходные данные Просмотреть построчно История
ace-yan Отправлено 3 лет назад 76f1d18
// Copyright (c) 2020 Huawei Technologies Co.,Ltd. All rights reserved.
//
// StratoVirt is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan
// PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
use error_chain::bail;
use std::fs::{File, OpenOptions};
use std::io::{Read, Result as IoResult, Write};
use std::os::unix::fs::OpenOptionsExt;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use vmm_sys_util::ioctl::{ioctl_with_mut_ref, ioctl_with_ref, ioctl_with_val};
use vmm_sys_util::{ioctl_expr, ioctl_ioc_nr, ioctl_ior_nr, ioctl_iow_nr};
use super::errors::{Result, ResultExt};
pub const TUN_F_CSUM: u32 = 1;
pub const TUN_F_TSO4: u32 = 2;
pub const TUN_F_TSO6: u32 = 4;
pub const TUN_F_UFO: u32 = 16;
pub const TUN_F_VIRTIO: u32 = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_UFO;
const IFF_TAP: u16 = 0x02;
pub const IFF_MULTI_QUEUE: u16 = 0x100;
const IFF_NO_PI: u16 = 0x1000;
const IFF_VNET_HDR: u16 = 0x4000;
const TUNTAP_PATH: &str = "/dev/net/tun";
ioctl_iow_nr!(TUNSETIFF, 84, 202, ::std::os::raw::c_int);
ioctl_ior_nr!(TUNGETFEATURES, 84, 207, ::std::os::raw::c_uint);
ioctl_iow_nr!(TUNSETOFFLOAD, 84, 208, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETVNETHDRSZ, 84, 216, ::std::os::raw::c_int);
#[repr(C)]
pub struct IfReq {
ifr_name: [u8; 16],
ifr_flags: u16,
}
pub struct Tap {
pub file: File,
}
impl Tap {
pub fn new(name: Option<&str>, fd: Option<RawFd>, queue_pairs: u16) -> Result<Self> {
let file;
if let Some(name) = name {
if name.len() > 15 {
return Err(format!("Open tap {} failed, name too long.", name).into());
}
let mut ifr_name = [0_u8; 16];
let (left, _) = ifr_name.split_at_mut(name.len());
left.copy_from_slice(name.as_bytes());
let mut if_req = IfReq {
ifr_name,
ifr_flags: IFF_TAP | IFF_NO_PI | IFF_VNET_HDR,
};
if queue_pairs > 1 {
if_req.ifr_flags |= IFF_MULTI_QUEUE;
}
let file_ = OpenOptions::new()
.read(true)
.write(true)
.custom_flags(libc::O_CLOEXEC | libc::O_NONBLOCK)
.open(TUNTAP_PATH)
.chain_err(|| format!("Open {} failed.", TUNTAP_PATH))?;
let ret = unsafe { ioctl_with_mut_ref(&file_, TUNSETIFF(), &mut if_req) };
if ret < 0 {
return Err(format!(
"Failed to set tap ifr flags, error is {}",
std::io::Error::last_os_error()
)
.into());
}
file = file_;
} else if let Some(fd) = fd {
file = unsafe {
libc::fcntl(fd, libc::F_SETFL, libc::O_NONBLOCK);
File::from_raw_fd(fd)
};
} else {
return Err(format!(
"Open tap failed, unsupported operation, error is {}",
std::io::Error::last_os_error()
)
.into());
}
let mut features = 0;
let ret = unsafe { ioctl_with_mut_ref(&file, TUNGETFEATURES(), &mut features) };
if ret < 0 {
return Err(format!(
"Failed to get tap features, error is {}.",
std::io::Error::last_os_error()
)
.into());
}
if (features & IFF_MULTI_QUEUE == 0) && queue_pairs > 1 {
bail!(
"Tap device doesn't support mq, but command set queue pairs {}.",
queue_pairs
);
}
Ok(Tap { file })
}
pub fn set_offload(&self, flags: u32) -> Result<()> {
let ret = unsafe { ioctl_with_val(&self.file, TUNSETOFFLOAD(), flags as libc::c_ulong) };
if ret < 0 {
return Err("ioctl TUNSETOFFLOAD failed.".to_string().into());
}
Ok(())
}
pub fn set_hdr_size(&self, len: u32) -> Result<()> {
let ret = unsafe { ioctl_with_ref(&self.file, TUNSETVNETHDRSZ(), &len) };
if ret < 0 {
return Err("ioctl TUNSETVNETHDRSZ failed.".to_string().into());
}
Ok(())
}
pub fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
self.file.read(buf)
}
pub fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
self.file.write(buf)
}
pub fn as_raw_fd(&self) -> RawFd {
self.file.as_raw_fd()
}
}
impl Clone for Tap {
fn clone(&self) -> Self {
Tap {
file: self.file.try_clone().unwrap(),
}
}
}

Комментарий ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://gitlife.ru/oschina-mirror/openeuler-stratovirt.git
git@gitlife.ru:oschina-mirror/openeuler-stratovirt.git
oschina-mirror
openeuler-stratovirt
openeuler-stratovirt
v2.2.0-rc2