From 951a189259b1fb58df74b4d83525cf27a9a36b85 Mon Sep 17 00:00:00 2001 From: Kuruyia Date: Sun, 31 Mar 2024 16:37:49 +0200 Subject: [PATCH] feat(vmm): add tap device creation This adds the automatic creation of a tap network interface on the host when a VMM is started. Those network interfaces are named `tapletX`. Two new CLI arguments were added to configure this interface, `--network-host-ip` and `--network-host-netmask`, which configures the IP address of the tap interface on the host side. Code was taken and adapted from the [cloud-hypervisor project](https://github.com/cloud-hypervisor/cloud-hypervisor/tree/main/net_util/src). Signed-off-by: Kuruyia --- src/vmm/Cargo.toml | 1 + src/vmm/src/args.rs | 10 +- src/vmm/src/core/mod.rs | 5 + src/vmm/src/core/network/mac.rs | 100 ++ src/vmm/src/core/network/mod.rs | 63 + src/vmm/src/core/network/net_gen/if_tun.rs | 332 +++++ src/vmm/src/core/network/net_gen/iff.rs | 1233 +++++++++++++++++++ src/vmm/src/core/network/net_gen/inn.rs | 299 +++++ src/vmm/src/core/network/net_gen/mod.rs | 59 + src/vmm/src/core/network/net_gen/sockios.rs | 100 ++ src/vmm/src/core/network/open_tap.rs | 77 ++ src/vmm/src/core/network/tap.rs | 318 +++++ src/vmm/src/core/vmm.rs | 18 +- src/vmm/src/main.rs | 3 +- 14 files changed, 2615 insertions(+), 3 deletions(-) create mode 100644 src/vmm/src/core/network/mac.rs create mode 100644 src/vmm/src/core/network/mod.rs create mode 100644 src/vmm/src/core/network/net_gen/if_tun.rs create mode 100644 src/vmm/src/core/network/net_gen/iff.rs create mode 100644 src/vmm/src/core/network/net_gen/inn.rs create mode 100644 src/vmm/src/core/network/net_gen/mod.rs create mode 100644 src/vmm/src/core/network/net_gen/sockios.rs create mode 100644 src/vmm/src/core/network/open_tap.rs create mode 100644 src/vmm/src/core/network/tap.rs diff --git a/src/vmm/Cargo.toml b/src/vmm/Cargo.toml index 8871605..e36726e 100644 --- a/src/vmm/Cargo.toml +++ b/src/vmm/Cargo.toml @@ -20,6 +20,7 @@ linux-loader = { version = "0.11.0", features = ["bzimage", "elf"] } log = "0.4.20" tracing = "0.1.40" tracing-subscriber = "0.3.18" +virtio-bindings = "0.2.2" vm-device = "0.1.0" vm-memory = { version = "0.14.0", features = ["backend-mmap"] } vm-superio = "0.7.0" diff --git a/src/vmm/src/args.rs b/src/vmm/src/args.rs index 4e91b70..0c694b8 100644 --- a/src/vmm/src/args.rs +++ b/src/vmm/src/args.rs @@ -1,5 +1,5 @@ //! Command-line arguments. -use std::path::PathBuf; +use std::{net::Ipv4Addr, path::PathBuf}; use clap::Parser; use clap_verbosity_flag::{InfoLevel, Verbosity}; @@ -21,6 +21,14 @@ pub struct CliArguments { #[clap(short, long, env, default_value = "512")] pub memory: u32, + /// IPv4 address of the host tap interface. + #[clap(long, env)] + pub network_host_ip: Ipv4Addr, + + /// Subnet mask of the host tap interface. + #[clap(long, env)] + pub network_host_netmask: Ipv4Addr, + /// Verbosity level. #[command(flatten)] pub verbose: Verbosity, diff --git a/src/vmm/src/core/mod.rs b/src/vmm/src/core/mod.rs index c698ceb..abdad5e 100644 --- a/src/vmm/src/core/mod.rs +++ b/src/vmm/src/core/mod.rs @@ -8,10 +8,13 @@ extern crate vm_superio; use linux_loader::loader; use std::io; +use self::network::open_tap; + mod cpu; mod devices; mod epoll_context; mod kernel; +mod network; pub mod vmm; #[derive(Debug)] @@ -48,6 +51,8 @@ pub enum Error { StdinWrite(vm_superio::serial::Error), /// Terminal configuration error TerminalConfigure(kvm_ioctls::Error), + // Tap open error + OpenTap(open_tap::Error), } /// Dedicated [`Result`](https://doc.rust-lang.org/std/result/) type. diff --git a/src/vmm/src/core/network/mac.rs b/src/vmm/src/core/network/mac.rs new file mode 100644 index 0000000..7b55927 --- /dev/null +++ b/src/vmm/src/core/network/mac.rs @@ -0,0 +1,100 @@ +// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// +// Portions Copyright 2017 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the THIRD-PARTY file. + +use std::fmt; +use std::io; +use std::str::FromStr; + +pub const MAC_ADDR_LEN: usize = 6; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct MacAddr { + bytes: [u8; MAC_ADDR_LEN], +} + +impl MacAddr { + pub fn parse_str(s: &S) -> Result + where + S: AsRef + ?Sized, + { + let v: Vec<&str> = s.as_ref().split(':').collect(); + let mut bytes = [0u8; MAC_ADDR_LEN]; + let common_err = Err(io::Error::new( + io::ErrorKind::Other, + format!("parsing of {} into a MAC address failed", s.as_ref()), + )); + + if v.len() != MAC_ADDR_LEN { + return common_err; + } + + for i in 0..MAC_ADDR_LEN { + if v[i].len() != 2 { + return common_err; + } + bytes[i] = u8::from_str_radix(v[i], 16).map_err(|e| { + io::Error::new( + io::ErrorKind::Other, + format!("parsing of {} into a MAC address failed: {}", s.as_ref(), e), + ) + })?; + } + + Ok(MacAddr { bytes }) + } + + // Does not check whether src.len() == MAC_ADDR_LEN. + #[inline] + pub fn from_bytes_unchecked(src: &[u8]) -> MacAddr { + // TODO: using something like std::mem::uninitialized could avoid the extra initialization, + // if this ever becomes a performance bottleneck. + let mut bytes = [0u8; MAC_ADDR_LEN]; + bytes[..].copy_from_slice(src); + + MacAddr { bytes } + } + + // An error can only occur if the slice length is different from MAC_ADDR_LEN. + #[inline] + pub fn from_bytes(src: &[u8]) -> Result { + if src.len() != MAC_ADDR_LEN { + return Err(io::Error::new( + io::ErrorKind::Other, + format!("invalid length of slice: {} vs {}", src.len(), MAC_ADDR_LEN), + )); + } + Ok(MacAddr::from_bytes_unchecked(src)) + } + + #[inline] + pub fn get_bytes(&self) -> &[u8] { + &self.bytes + } +} + +impl fmt::Display for MacAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let b = &self.bytes; + write!( + f, + "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", + b[0], b[1], b[2], b[3], b[4], b[5] + ) + } +} + +pub enum MacAddrParseError { + InvalidValue(String), +} + +impl FromStr for MacAddr { + type Err = MacAddrParseError; + + fn from_str(s: &str) -> std::result::Result { + MacAddr::parse_str(s).map_err(|_| MacAddrParseError::InvalidValue(s.to_owned())) + } +} diff --git a/src/vmm/src/core/network/mod.rs b/src/vmm/src/core/network/mod.rs new file mode 100644 index 0000000..c23f04a --- /dev/null +++ b/src/vmm/src/core/network/mod.rs @@ -0,0 +1,63 @@ +// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// +// Portions Copyright 2017 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the THIRD-PARTY file. + +use std::{io, mem, net, os::fd::FromRawFd}; + +use virtio_bindings::virtio_net::virtio_net_hdr_v1; + +pub(crate) mod mac; +pub(crate) mod net_gen; +pub(crate) mod open_tap; +pub(crate) mod tap; + +#[derive(Debug)] +pub enum Error { + CreateSocket(io::Error), +} + +/// Create a sockaddr_in from an IPv4 address, and expose it as +/// an opaque sockaddr suitable for usage by socket ioctls. +fn create_sockaddr(ip_addr: net::Ipv4Addr) -> net_gen::sockaddr { + // IPv4 addresses big-endian (network order), but Ipv4Addr will give us + // a view of those bytes directly so we can avoid any endian trickiness. + let addr_in = net_gen::sockaddr_in { + sin_family: net_gen::AF_INET as u16, + sin_port: 0, + // SAFETY: ip_addr can be safely transmute to in_addr + sin_addr: unsafe { mem::transmute(ip_addr.octets()) }, + __pad: [0; 8usize], + }; + + // SAFETY: addr_in can be safely transmute to sockaddr + unsafe { mem::transmute(addr_in) } +} + +fn create_inet_socket() -> Result { + // SAFETY: we check the return value. + let sock = unsafe { libc::socket(libc::AF_INET, libc::SOCK_DGRAM, 0) }; + if sock < 0 { + return Err(Error::CreateSocket(io::Error::last_os_error())); + } + + // SAFETY: nothing else will use or hold onto the raw sock fd. + Ok(unsafe { net::UdpSocket::from_raw_fd(sock) }) +} + +fn create_unix_socket() -> Result { + // SAFETY: we check the return value. + let sock = unsafe { libc::socket(libc::AF_UNIX, libc::SOCK_DGRAM, 0) }; + if sock < 0 { + return Err(Error::CreateSocket(io::Error::last_os_error())); + } + + // SAFETY: nothing else will use or hold onto the raw sock fd. + Ok(unsafe { net::UdpSocket::from_raw_fd(sock) }) +} + +fn vnet_hdr_len() -> usize { + std::mem::size_of::() +} diff --git a/src/vmm/src/core/network/net_gen/if_tun.rs b/src/vmm/src/core/network/net_gen/if_tun.rs new file mode 100644 index 0000000..e88e555 --- /dev/null +++ b/src/vmm/src/core/network/net_gen/if_tun.rs @@ -0,0 +1,332 @@ +// Copyright © 2021 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] + +// bindgen /usr/include/linux/if_tun.h --no-layout-tests + +/* automatically generated by rust-bindgen 0.58.1 */ + +#[repr(C)] +#[derive(Default)] +pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); +#[allow(clippy::missing_safety_doc)] +impl __IncompleteArrayField { + #[inline] + pub const fn new() -> Self { + __IncompleteArrayField(::std::marker::PhantomData, []) + } + #[inline] + pub fn as_ptr(&self) -> *const T { + self as *const _ as *const T + } + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut T { + self as *mut _ as *mut T + } + #[inline] + pub unsafe fn as_slice(&self, len: usize) -> &[T] { + ::std::slice::from_raw_parts(self.as_ptr(), len) + } + #[inline] + pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { + ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + } +} +impl ::std::fmt::Debug for __IncompleteArrayField { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + fmt.write_str("__IncompleteArrayField") + } +} +pub const __BITS_PER_LONG: u32 = 64; +pub const __FD_SETSIZE: u32 = 1024; +pub const ETH_ALEN: u32 = 6; +pub const ETH_TLEN: u32 = 2; +pub const ETH_HLEN: u32 = 14; +pub const ETH_ZLEN: u32 = 60; +pub const ETH_DATA_LEN: u32 = 1500; +pub const ETH_FRAME_LEN: u32 = 1514; +pub const ETH_FCS_LEN: u32 = 4; +pub const ETH_MIN_MTU: u32 = 68; +pub const ETH_MAX_MTU: u32 = 65535; +pub const ETH_P_LOOP: u32 = 96; +pub const ETH_P_PUP: u32 = 512; +pub const ETH_P_PUPAT: u32 = 513; +pub const ETH_P_TSN: u32 = 8944; +pub const ETH_P_ERSPAN2: u32 = 8939; +pub const ETH_P_IP: u32 = 2048; +pub const ETH_P_X25: u32 = 2053; +pub const ETH_P_ARP: u32 = 2054; +pub const ETH_P_BPQ: u32 = 2303; +pub const ETH_P_IEEEPUP: u32 = 2560; +pub const ETH_P_IEEEPUPAT: u32 = 2561; +pub const ETH_P_BATMAN: u32 = 17157; +pub const ETH_P_DEC: u32 = 24576; +pub const ETH_P_DNA_DL: u32 = 24577; +pub const ETH_P_DNA_RC: u32 = 24578; +pub const ETH_P_DNA_RT: u32 = 24579; +pub const ETH_P_LAT: u32 = 24580; +pub const ETH_P_DIAG: u32 = 24581; +pub const ETH_P_CUST: u32 = 24582; +pub const ETH_P_SCA: u32 = 24583; +pub const ETH_P_TEB: u32 = 25944; +pub const ETH_P_RARP: u32 = 32821; +pub const ETH_P_ATALK: u32 = 32923; +pub const ETH_P_AARP: u32 = 33011; +pub const ETH_P_8021Q: u32 = 33024; +pub const ETH_P_ERSPAN: u32 = 35006; +pub const ETH_P_IPX: u32 = 33079; +pub const ETH_P_IPV6: u32 = 34525; +pub const ETH_P_PAUSE: u32 = 34824; +pub const ETH_P_SLOW: u32 = 34825; +pub const ETH_P_WCCP: u32 = 34878; +pub const ETH_P_MPLS_UC: u32 = 34887; +pub const ETH_P_MPLS_MC: u32 = 34888; +pub const ETH_P_ATMMPOA: u32 = 34892; +pub const ETH_P_PPP_DISC: u32 = 34915; +pub const ETH_P_PPP_SES: u32 = 34916; +pub const ETH_P_LINK_CTL: u32 = 34924; +pub const ETH_P_ATMFATE: u32 = 34948; +pub const ETH_P_PAE: u32 = 34958; +pub const ETH_P_AOE: u32 = 34978; +pub const ETH_P_8021AD: u32 = 34984; +pub const ETH_P_802_EX1: u32 = 34997; +pub const ETH_P_PREAUTH: u32 = 35015; +pub const ETH_P_TIPC: u32 = 35018; +pub const ETH_P_LLDP: u32 = 35020; +pub const ETH_P_MRP: u32 = 35043; +pub const ETH_P_MACSEC: u32 = 35045; +pub const ETH_P_8021AH: u32 = 35047; +pub const ETH_P_MVRP: u32 = 35061; +pub const ETH_P_1588: u32 = 35063; +pub const ETH_P_NCSI: u32 = 35064; +pub const ETH_P_PRP: u32 = 35067; +pub const ETH_P_FCOE: u32 = 35078; +pub const ETH_P_IBOE: u32 = 35093; +pub const ETH_P_TDLS: u32 = 35085; +pub const ETH_P_FIP: u32 = 35092; +pub const ETH_P_80221: u32 = 35095; +pub const ETH_P_HSR: u32 = 35119; +pub const ETH_P_NSH: u32 = 35151; +pub const ETH_P_LOOPBACK: u32 = 36864; +pub const ETH_P_QINQ1: u32 = 37120; +pub const ETH_P_QINQ2: u32 = 37376; +pub const ETH_P_QINQ3: u32 = 37632; +pub const ETH_P_EDSA: u32 = 56026; +pub const ETH_P_DSA_8021Q: u32 = 56027; +pub const ETH_P_IFE: u32 = 60734; +pub const ETH_P_AF_IUCV: u32 = 64507; +pub const ETH_P_802_3_MIN: u32 = 1536; +pub const ETH_P_802_3: u32 = 1; +pub const ETH_P_AX25: u32 = 2; +pub const ETH_P_ALL: u32 = 3; +pub const ETH_P_802_2: u32 = 4; +pub const ETH_P_SNAP: u32 = 5; +pub const ETH_P_DDCMP: u32 = 6; +pub const ETH_P_WAN_PPP: u32 = 7; +pub const ETH_P_PPP_MP: u32 = 8; +pub const ETH_P_LOCALTALK: u32 = 9; +pub const ETH_P_CAN: u32 = 12; +pub const ETH_P_CANFD: u32 = 13; +pub const ETH_P_PPPTALK: u32 = 16; +pub const ETH_P_TR_802_2: u32 = 17; +pub const ETH_P_MOBITEX: u32 = 21; +pub const ETH_P_CONTROL: u32 = 22; +pub const ETH_P_IRDA: u32 = 23; +pub const ETH_P_ECONET: u32 = 24; +pub const ETH_P_HDLC: u32 = 25; +pub const ETH_P_ARCNET: u32 = 26; +pub const ETH_P_DSA: u32 = 27; +pub const ETH_P_TRAILER: u32 = 28; +pub const ETH_P_PHONET: u32 = 245; +pub const ETH_P_IEEE802154: u32 = 246; +pub const ETH_P_CAIF: u32 = 247; +pub const ETH_P_XDSA: u32 = 248; +pub const ETH_P_MAP: u32 = 249; +pub const __UAPI_DEF_ETHHDR: u32 = 1; +pub const BPF_LD: u32 = 0; +pub const BPF_LDX: u32 = 1; +pub const BPF_ST: u32 = 2; +pub const BPF_STX: u32 = 3; +pub const BPF_ALU: u32 = 4; +pub const BPF_JMP: u32 = 5; +pub const BPF_RET: u32 = 6; +pub const BPF_MISC: u32 = 7; +pub const BPF_W: u32 = 0; +pub const BPF_H: u32 = 8; +pub const BPF_B: u32 = 16; +pub const BPF_IMM: u32 = 0; +pub const BPF_ABS: u32 = 32; +pub const BPF_IND: u32 = 64; +pub const BPF_MEM: u32 = 96; +pub const BPF_LEN: u32 = 128; +pub const BPF_MSH: u32 = 160; +pub const BPF_ADD: u32 = 0; +pub const BPF_SUB: u32 = 16; +pub const BPF_MUL: u32 = 32; +pub const BPF_DIV: u32 = 48; +pub const BPF_OR: u32 = 64; +pub const BPF_AND: u32 = 80; +pub const BPF_LSH: u32 = 96; +pub const BPF_RSH: u32 = 112; +pub const BPF_NEG: u32 = 128; +pub const BPF_MOD: u32 = 144; +pub const BPF_XOR: u32 = 160; +pub const BPF_JA: u32 = 0; +pub const BPF_JEQ: u32 = 16; +pub const BPF_JGT: u32 = 32; +pub const BPF_JGE: u32 = 48; +pub const BPF_JSET: u32 = 64; +pub const BPF_K: u32 = 0; +pub const BPF_X: u32 = 8; +pub const BPF_MAXINSNS: u32 = 4096; +pub const BPF_MAJOR_VERSION: u32 = 1; +pub const BPF_MINOR_VERSION: u32 = 1; +pub const BPF_A: u32 = 16; +pub const BPF_TAX: u32 = 0; +pub const BPF_TXA: u32 = 128; +pub const BPF_MEMWORDS: u32 = 16; +pub const SKF_AD_OFF: i32 = -4096; +pub const SKF_AD_PROTOCOL: u32 = 0; +pub const SKF_AD_PKTTYPE: u32 = 4; +pub const SKF_AD_IFINDEX: u32 = 8; +pub const SKF_AD_NLATTR: u32 = 12; +pub const SKF_AD_NLATTR_NEST: u32 = 16; +pub const SKF_AD_MARK: u32 = 20; +pub const SKF_AD_QUEUE: u32 = 24; +pub const SKF_AD_HATYPE: u32 = 28; +pub const SKF_AD_RXHASH: u32 = 32; +pub const SKF_AD_CPU: u32 = 36; +pub const SKF_AD_ALU_XOR_X: u32 = 40; +pub const SKF_AD_VLAN_TAG: u32 = 44; +pub const SKF_AD_VLAN_TAG_PRESENT: u32 = 48; +pub const SKF_AD_PAY_OFFSET: u32 = 52; +pub const SKF_AD_RANDOM: u32 = 56; +pub const SKF_AD_VLAN_TPID: u32 = 60; +pub const SKF_AD_MAX: u32 = 64; +pub const SKF_NET_OFF: i32 = -1048576; +pub const SKF_LL_OFF: i32 = -2097152; +pub const BPF_NET_OFF: i32 = -1048576; +pub const BPF_LL_OFF: i32 = -2097152; +pub const TUN_READQ_SIZE: u32 = 500; +pub const TUN_TYPE_MASK: u32 = 15; +pub const IFF_TUN: u32 = 1; +pub const IFF_TAP: u32 = 2; +pub const IFF_NAPI: u32 = 16; +pub const IFF_NAPI_FRAGS: u32 = 32; +pub const IFF_NO_PI: u32 = 4096; +pub const IFF_ONE_QUEUE: u32 = 8192; +pub const IFF_VNET_HDR: u32 = 16384; +pub const IFF_TUN_EXCL: u32 = 32768; +pub const IFF_MULTI_QUEUE: u32 = 256; +pub const IFF_ATTACH_QUEUE: u32 = 512; +pub const IFF_DETACH_QUEUE: u32 = 1024; +pub const IFF_PERSIST: u32 = 2048; +pub const IFF_NOFILTER: u32 = 4096; +pub const TUN_TX_TIMESTAMP: u32 = 1; +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_TSO_ECN: u32 = 8; +pub const TUN_F_UFO: u32 = 16; +pub const TUN_PKT_STRIP: u32 = 1; +pub const TUN_FLT_ALLMULTI: u32 = 1; +pub type __s8 = ::std::os::raw::c_schar; +pub type __u8 = ::std::os::raw::c_uchar; +pub type __s16 = ::std::os::raw::c_short; +pub type __u16 = ::std::os::raw::c_ushort; +pub type __s32 = ::std::os::raw::c_int; +pub type __u32 = ::std::os::raw::c_uint; +pub type __s64 = ::std::os::raw::c_longlong; +pub type __u64 = ::std::os::raw::c_ulonglong; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_fd_set { + pub fds_bits: [::std::os::raw::c_ulong; 16usize], +} +pub type __kernel_sighandler_t = + ::std::option::Option; +pub type __kernel_key_t = ::std::os::raw::c_int; +pub type __kernel_mqd_t = ::std::os::raw::c_int; +pub type __kernel_old_uid_t = ::std::os::raw::c_ushort; +pub type __kernel_old_gid_t = ::std::os::raw::c_ushort; +pub type __kernel_old_dev_t = ::std::os::raw::c_ulong; +pub type __kernel_long_t = ::std::os::raw::c_long; +pub type __kernel_ulong_t = ::std::os::raw::c_ulong; +pub type __kernel_ino_t = __kernel_ulong_t; +pub type __kernel_mode_t = ::std::os::raw::c_uint; +pub type __kernel_pid_t = ::std::os::raw::c_int; +pub type __kernel_ipc_pid_t = ::std::os::raw::c_int; +pub type __kernel_uid_t = ::std::os::raw::c_uint; +pub type __kernel_gid_t = ::std::os::raw::c_uint; +pub type __kernel_suseconds_t = __kernel_long_t; +pub type __kernel_daddr_t = ::std::os::raw::c_int; +pub type __kernel_uid32_t = ::std::os::raw::c_uint; +pub type __kernel_gid32_t = ::std::os::raw::c_uint; +pub type __kernel_size_t = __kernel_ulong_t; +pub type __kernel_ssize_t = __kernel_long_t; +pub type __kernel_ptrdiff_t = __kernel_long_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_fsid_t { + pub val: [::std::os::raw::c_int; 2usize], +} +pub type __kernel_off_t = __kernel_long_t; +pub type __kernel_loff_t = ::std::os::raw::c_longlong; +pub type __kernel_old_time_t = __kernel_long_t; +pub type __kernel_time_t = __kernel_long_t; +pub type __kernel_time64_t = ::std::os::raw::c_longlong; +pub type __kernel_clock_t = __kernel_long_t; +pub type __kernel_timer_t = ::std::os::raw::c_int; +pub type __kernel_clockid_t = ::std::os::raw::c_int; +pub type __kernel_caddr_t = *mut ::std::os::raw::c_char; +pub type __kernel_uid16_t = ::std::os::raw::c_ushort; +pub type __kernel_gid16_t = ::std::os::raw::c_ushort; +pub type __le16 = __u16; +pub type __be16 = __u16; +pub type __le32 = __u32; +pub type __be32 = __u32; +pub type __le64 = __u64; +pub type __be64 = __u64; +pub type __sum16 = __u16; +pub type __wsum = __u32; +pub type __poll_t = ::std::os::raw::c_uint; +#[repr(C, packed)] +#[derive(Debug, Copy, Clone)] +pub struct ethhdr { + pub h_dest: [::std::os::raw::c_uchar; 6usize], + pub h_source: [::std::os::raw::c_uchar; 6usize], + pub h_proto: __be16, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sock_filter { + pub code: __u16, + pub jt: __u8, + pub jf: __u8, + pub k: __u32, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sock_fprog { + pub len: ::std::os::raw::c_ushort, + pub filter: *mut sock_filter, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct tun_pi { + pub flags: __u16, + pub proto: __be16, +} +#[repr(C)] +#[derive(Debug)] +pub struct tun_filter { + pub flags: __u16, + pub count: __u16, + pub addr: __IncompleteArrayField<[__u8; 6usize]>, +} diff --git a/src/vmm/src/core/network/net_gen/iff.rs b/src/vmm/src/core/network/net_gen/iff.rs new file mode 100644 index 0000000..39f2111 --- /dev/null +++ b/src/vmm/src/core/network/net_gen/iff.rs @@ -0,0 +1,1233 @@ +// Copyright © 2021 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] + +// bindgen /usr/include/linux/if.h --no-layout-tests + +/* automatically generated by rust-bindgen 0.58.1 */ + +#[repr(C)] +#[derive(Default)] +pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); +#[allow(clippy::missing_safety_doc)] +impl __IncompleteArrayField { + #[inline] + pub const fn new() -> Self { + __IncompleteArrayField(::std::marker::PhantomData, []) + } + #[inline] + pub fn as_ptr(&self) -> *const T { + self as *const _ as *const T + } + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut T { + self as *mut _ as *mut T + } + #[inline] + pub unsafe fn as_slice(&self, len: usize) -> &[T] { + ::std::slice::from_raw_parts(self.as_ptr(), len) + } + #[inline] + pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { + ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + } +} +impl ::std::fmt::Debug for __IncompleteArrayField { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + fmt.write_str("__IncompleteArrayField") + } +} +pub const __UAPI_DEF_IF_IFCONF: u32 = 1; +pub const __UAPI_DEF_IF_IFMAP: u32 = 1; +pub const __UAPI_DEF_IF_IFNAMSIZ: u32 = 1; +pub const __UAPI_DEF_IF_IFREQ: u32 = 1; +pub const __UAPI_DEF_IF_NET_DEVICE_FLAGS: u32 = 1; +pub const __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO: u32 = 1; +pub const __UAPI_DEF_IN_ADDR: u32 = 1; +pub const __UAPI_DEF_IN_IPPROTO: u32 = 1; +pub const __UAPI_DEF_IN_PKTINFO: u32 = 1; +pub const __UAPI_DEF_IP_MREQ: u32 = 1; +pub const __UAPI_DEF_SOCKADDR_IN: u32 = 1; +pub const __UAPI_DEF_IN_CLASS: u32 = 1; +pub const __UAPI_DEF_IN6_ADDR: u32 = 1; +pub const __UAPI_DEF_IN6_ADDR_ALT: u32 = 1; +pub const __UAPI_DEF_SOCKADDR_IN6: u32 = 1; +pub const __UAPI_DEF_IPV6_MREQ: u32 = 1; +pub const __UAPI_DEF_IPPROTO_V6: u32 = 1; +pub const __UAPI_DEF_IPV6_OPTIONS: u32 = 1; +pub const __UAPI_DEF_IN6_PKTINFO: u32 = 1; +pub const __UAPI_DEF_IP6_MTUINFO: u32 = 1; +pub const __UAPI_DEF_SOCKADDR_IPX: u32 = 1; +pub const __UAPI_DEF_IPX_ROUTE_DEFINITION: u32 = 1; +pub const __UAPI_DEF_IPX_INTERFACE_DEFINITION: u32 = 1; +pub const __UAPI_DEF_IPX_CONFIG_DATA: u32 = 1; +pub const __UAPI_DEF_IPX_ROUTE_DEF: u32 = 1; +pub const __UAPI_DEF_XATTR: u32 = 1; +pub const __BITS_PER_LONG: u32 = 64; +pub const __FD_SETSIZE: u32 = 1024; +pub const _K_SS_MAXSIZE: u32 = 128; +pub const _SYS_SOCKET_H: u32 = 1; +pub const _FEATURES_H: u32 = 1; +pub const _DEFAULT_SOURCE: u32 = 1; +pub const __GLIBC_USE_ISOC2X: u32 = 0; +pub const __USE_ISOC11: u32 = 1; +pub const __USE_ISOC99: u32 = 1; +pub const __USE_ISOC95: u32 = 1; +pub const __USE_POSIX_IMPLICITLY: u32 = 1; +pub const _POSIX_SOURCE: u32 = 1; +pub const _POSIX_C_SOURCE: u32 = 200809; +pub const __USE_POSIX: u32 = 1; +pub const __USE_POSIX2: u32 = 1; +pub const __USE_POSIX199309: u32 = 1; +pub const __USE_POSIX199506: u32 = 1; +pub const __USE_XOPEN2K: u32 = 1; +pub const __USE_XOPEN2K8: u32 = 1; +pub const _ATFILE_SOURCE: u32 = 1; +pub const __USE_MISC: u32 = 1; +pub const __USE_ATFILE: u32 = 1; +pub const __USE_FORTIFY_LEVEL: u32 = 0; +pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0; +pub const __GLIBC_USE_DEPRECATED_SCANF: u32 = 0; +pub const _STDC_PREDEF_H: u32 = 1; +pub const __STDC_IEC_559__: u32 = 1; +pub const __STDC_IEC_559_COMPLEX__: u32 = 1; +pub const __STDC_ISO_10646__: u32 = 201706; +pub const __GNU_LIBRARY__: u32 = 6; +pub const __GLIBC__: u32 = 2; +pub const __GLIBC_MINOR__: u32 = 32; +pub const _SYS_CDEFS_H: u32 = 1; +pub const __glibc_c99_flexarr_available: u32 = 1; +pub const __WORDSIZE: u32 = 64; +pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; +pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI: u32 = 0; +pub const __HAVE_GENERIC_SELECTION: u32 = 1; +pub const __iovec_defined: u32 = 1; +pub const _SYS_TYPES_H: u32 = 1; +pub const _BITS_TYPES_H: u32 = 1; +pub const __TIMESIZE: u32 = 64; +pub const _BITS_TYPESIZES_H: u32 = 1; +pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; +pub const __INO_T_MATCHES_INO64_T: u32 = 1; +pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1; +pub const __STATFS_MATCHES_STATFS64: u32 = 1; +pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64: u32 = 1; +pub const _BITS_TIME64_H: u32 = 1; +pub const __clock_t_defined: u32 = 1; +pub const __clockid_t_defined: u32 = 1; +pub const __time_t_defined: u32 = 1; +pub const __timer_t_defined: u32 = 1; +pub const _BITS_STDINT_INTN_H: u32 = 1; +pub const __BIT_TYPES_DEFINED__: u32 = 1; +pub const _ENDIAN_H: u32 = 1; +pub const _BITS_ENDIAN_H: u32 = 1; +pub const __LITTLE_ENDIAN: u32 = 1234; +pub const __BIG_ENDIAN: u32 = 4321; +pub const __PDP_ENDIAN: u32 = 3412; +pub const _BITS_ENDIANNESS_H: u32 = 1; +pub const __BYTE_ORDER: u32 = 1234; +pub const __FLOAT_WORD_ORDER: u32 = 1234; +pub const LITTLE_ENDIAN: u32 = 1234; +pub const BIG_ENDIAN: u32 = 4321; +pub const PDP_ENDIAN: u32 = 3412; +pub const BYTE_ORDER: u32 = 1234; +pub const _BITS_BYTESWAP_H: u32 = 1; +pub const _BITS_UINTN_IDENTITY_H: u32 = 1; +pub const _SYS_SELECT_H: u32 = 1; +pub const __sigset_t_defined: u32 = 1; +pub const __timeval_defined: u32 = 1; +pub const _STRUCT_TIMESPEC: u32 = 1; +pub const FD_SETSIZE: u32 = 1024; +pub const _BITS_PTHREADTYPES_COMMON_H: u32 = 1; +pub const _THREAD_SHARED_TYPES_H: u32 = 1; +pub const _BITS_PTHREADTYPES_ARCH_H: u32 = 1; +pub const __SIZEOF_PTHREAD_MUTEX_T: u32 = 40; +pub const __SIZEOF_PTHREAD_ATTR_T: u32 = 56; +pub const __SIZEOF_PTHREAD_RWLOCK_T: u32 = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: u32 = 32; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: u32 = 4; +pub const __SIZEOF_PTHREAD_COND_T: u32 = 48; +pub const __SIZEOF_PTHREAD_CONDATTR_T: u32 = 4; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: u32 = 8; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: u32 = 4; +pub const _THREAD_MUTEX_INTERNAL_H: u32 = 1; +pub const __PTHREAD_MUTEX_HAVE_PREV: u32 = 1; +pub const __have_pthread_attr_t: u32 = 1; +pub const PF_UNSPEC: u32 = 0; +pub const PF_LOCAL: u32 = 1; +pub const PF_UNIX: u32 = 1; +pub const PF_FILE: u32 = 1; +pub const PF_INET: u32 = 2; +pub const PF_AX25: u32 = 3; +pub const PF_IPX: u32 = 4; +pub const PF_APPLETALK: u32 = 5; +pub const PF_NETROM: u32 = 6; +pub const PF_BRIDGE: u32 = 7; +pub const PF_ATMPVC: u32 = 8; +pub const PF_X25: u32 = 9; +pub const PF_INET6: u32 = 10; +pub const PF_ROSE: u32 = 11; +pub const PF_DECnet: u32 = 12; +pub const PF_NETBEUI: u32 = 13; +pub const PF_SECURITY: u32 = 14; +pub const PF_KEY: u32 = 15; +pub const PF_NETLINK: u32 = 16; +pub const PF_ROUTE: u32 = 16; +pub const PF_PACKET: u32 = 17; +pub const PF_ASH: u32 = 18; +pub const PF_ECONET: u32 = 19; +pub const PF_ATMSVC: u32 = 20; +pub const PF_RDS: u32 = 21; +pub const PF_SNA: u32 = 22; +pub const PF_IRDA: u32 = 23; +pub const PF_PPPOX: u32 = 24; +pub const PF_WANPIPE: u32 = 25; +pub const PF_LLC: u32 = 26; +pub const PF_IB: u32 = 27; +pub const PF_MPLS: u32 = 28; +pub const PF_CAN: u32 = 29; +pub const PF_TIPC: u32 = 30; +pub const PF_BLUETOOTH: u32 = 31; +pub const PF_IUCV: u32 = 32; +pub const PF_RXRPC: u32 = 33; +pub const PF_ISDN: u32 = 34; +pub const PF_PHONET: u32 = 35; +pub const PF_IEEE802154: u32 = 36; +pub const PF_CAIF: u32 = 37; +pub const PF_ALG: u32 = 38; +pub const PF_NFC: u32 = 39; +pub const PF_VSOCK: u32 = 40; +pub const PF_KCM: u32 = 41; +pub const PF_QIPCRTR: u32 = 42; +pub const PF_SMC: u32 = 43; +pub const PF_XDP: u32 = 44; +pub const PF_MAX: u32 = 45; +pub const AF_UNSPEC: u32 = 0; +pub const AF_LOCAL: u32 = 1; +pub const AF_UNIX: u32 = 1; +pub const AF_FILE: u32 = 1; +pub const AF_INET: u32 = 2; +pub const AF_AX25: u32 = 3; +pub const AF_IPX: u32 = 4; +pub const AF_APPLETALK: u32 = 5; +pub const AF_NETROM: u32 = 6; +pub const AF_BRIDGE: u32 = 7; +pub const AF_ATMPVC: u32 = 8; +pub const AF_X25: u32 = 9; +pub const AF_INET6: u32 = 10; +pub const AF_ROSE: u32 = 11; +pub const AF_DECnet: u32 = 12; +pub const AF_NETBEUI: u32 = 13; +pub const AF_SECURITY: u32 = 14; +pub const AF_KEY: u32 = 15; +pub const AF_NETLINK: u32 = 16; +pub const AF_ROUTE: u32 = 16; +pub const AF_PACKET: u32 = 17; +pub const AF_ASH: u32 = 18; +pub const AF_ECONET: u32 = 19; +pub const AF_ATMSVC: u32 = 20; +pub const AF_RDS: u32 = 21; +pub const AF_SNA: u32 = 22; +pub const AF_IRDA: u32 = 23; +pub const AF_PPPOX: u32 = 24; +pub const AF_WANPIPE: u32 = 25; +pub const AF_LLC: u32 = 26; +pub const AF_IB: u32 = 27; +pub const AF_MPLS: u32 = 28; +pub const AF_CAN: u32 = 29; +pub const AF_TIPC: u32 = 30; +pub const AF_BLUETOOTH: u32 = 31; +pub const AF_IUCV: u32 = 32; +pub const AF_RXRPC: u32 = 33; +pub const AF_ISDN: u32 = 34; +pub const AF_PHONET: u32 = 35; +pub const AF_IEEE802154: u32 = 36; +pub const AF_CAIF: u32 = 37; +pub const AF_ALG: u32 = 38; +pub const AF_NFC: u32 = 39; +pub const AF_VSOCK: u32 = 40; +pub const AF_KCM: u32 = 41; +pub const AF_QIPCRTR: u32 = 42; +pub const AF_SMC: u32 = 43; +pub const AF_XDP: u32 = 44; +pub const AF_MAX: u32 = 45; +pub const SOL_RAW: u32 = 255; +pub const SOL_DECNET: u32 = 261; +pub const SOL_X25: u32 = 262; +pub const SOL_PACKET: u32 = 263; +pub const SOL_ATM: u32 = 264; +pub const SOL_AAL: u32 = 265; +pub const SOL_IRDA: u32 = 266; +pub const SOL_NETBEUI: u32 = 267; +pub const SOL_LLC: u32 = 268; +pub const SOL_DCCP: u32 = 269; +pub const SOL_NETLINK: u32 = 270; +pub const SOL_TIPC: u32 = 271; +pub const SOL_RXRPC: u32 = 272; +pub const SOL_PPPOL2TP: u32 = 273; +pub const SOL_BLUETOOTH: u32 = 274; +pub const SOL_PNPIPE: u32 = 275; +pub const SOL_RDS: u32 = 276; +pub const SOL_IUCV: u32 = 277; +pub const SOL_CAIF: u32 = 278; +pub const SOL_ALG: u32 = 279; +pub const SOL_NFC: u32 = 280; +pub const SOL_KCM: u32 = 281; +pub const SOL_TLS: u32 = 282; +pub const SOL_XDP: u32 = 283; +pub const SOMAXCONN: u32 = 4096; +pub const _BITS_SOCKADDR_H: u32 = 1; +pub const _SS_SIZE: u32 = 128; +pub const FIOSETOWN: u32 = 35073; +pub const SIOCSPGRP: u32 = 35074; +pub const FIOGETOWN: u32 = 35075; +pub const SIOCGPGRP: u32 = 35076; +pub const SIOCATMARK: u32 = 35077; +pub const SIOCGSTAMP_OLD: u32 = 35078; +pub const SIOCGSTAMPNS_OLD: u32 = 35079; +pub const SOL_SOCKET: u32 = 1; +pub const SO_DEBUG: u32 = 1; +pub const SO_REUSEADDR: u32 = 2; +pub const SO_TYPE: u32 = 3; +pub const SO_ERROR: u32 = 4; +pub const SO_DONTROUTE: u32 = 5; +pub const SO_BROADCAST: u32 = 6; +pub const SO_SNDBUF: u32 = 7; +pub const SO_RCVBUF: u32 = 8; +pub const SO_SNDBUFFORCE: u32 = 32; +pub const SO_RCVBUFFORCE: u32 = 33; +pub const SO_KEEPALIVE: u32 = 9; +pub const SO_OOBINLINE: u32 = 10; +pub const SO_NO_CHECK: u32 = 11; +pub const SO_PRIORITY: u32 = 12; +pub const SO_LINGER: u32 = 13; +pub const SO_BSDCOMPAT: u32 = 14; +pub const SO_REUSEPORT: u32 = 15; +pub const SO_PASSCRED: u32 = 16; +pub const SO_PEERCRED: u32 = 17; +pub const SO_RCVLOWAT: u32 = 18; +pub const SO_SNDLOWAT: u32 = 19; +pub const SO_RCVTIMEO_OLD: u32 = 20; +pub const SO_SNDTIMEO_OLD: u32 = 21; +pub const SO_SECURITY_AUTHENTICATION: u32 = 22; +pub const SO_SECURITY_ENCRYPTION_TRANSPORT: u32 = 23; +pub const SO_SECURITY_ENCRYPTION_NETWORK: u32 = 24; +pub const SO_BINDTODEVICE: u32 = 25; +pub const SO_ATTACH_FILTER: u32 = 26; +pub const SO_DETACH_FILTER: u32 = 27; +pub const SO_GET_FILTER: u32 = 26; +pub const SO_PEERNAME: u32 = 28; +pub const SO_ACCEPTCONN: u32 = 30; +pub const SO_PEERSEC: u32 = 31; +pub const SO_PASSSEC: u32 = 34; +pub const SO_MARK: u32 = 36; +pub const SO_PROTOCOL: u32 = 38; +pub const SO_DOMAIN: u32 = 39; +pub const SO_RXQ_OVFL: u32 = 40; +pub const SO_WIFI_STATUS: u32 = 41; +pub const SCM_WIFI_STATUS: u32 = 41; +pub const SO_PEEK_OFF: u32 = 42; +pub const SO_NOFCS: u32 = 43; +pub const SO_LOCK_FILTER: u32 = 44; +pub const SO_SELECT_ERR_QUEUE: u32 = 45; +pub const SO_BUSY_POLL: u32 = 46; +pub const SO_MAX_PACING_RATE: u32 = 47; +pub const SO_BPF_EXTENSIONS: u32 = 48; +pub const SO_INCOMING_CPU: u32 = 49; +pub const SO_ATTACH_BPF: u32 = 50; +pub const SO_DETACH_BPF: u32 = 27; +pub const SO_ATTACH_REUSEPORT_CBPF: u32 = 51; +pub const SO_ATTACH_REUSEPORT_EBPF: u32 = 52; +pub const SO_CNX_ADVICE: u32 = 53; +pub const SCM_TIMESTAMPING_OPT_STATS: u32 = 54; +pub const SO_MEMINFO: u32 = 55; +pub const SO_INCOMING_NAPI_ID: u32 = 56; +pub const SO_COOKIE: u32 = 57; +pub const SCM_TIMESTAMPING_PKTINFO: u32 = 58; +pub const SO_PEERGROUPS: u32 = 59; +pub const SO_ZEROCOPY: u32 = 60; +pub const SO_TXTIME: u32 = 61; +pub const SCM_TXTIME: u32 = 61; +pub const SO_BINDTOIFINDEX: u32 = 62; +pub const SO_TIMESTAMP_OLD: u32 = 29; +pub const SO_TIMESTAMPNS_OLD: u32 = 35; +pub const SO_TIMESTAMPING_OLD: u32 = 37; +pub const SO_TIMESTAMP_NEW: u32 = 63; +pub const SO_TIMESTAMPNS_NEW: u32 = 64; +pub const SO_TIMESTAMPING_NEW: u32 = 65; +pub const SO_RCVTIMEO_NEW: u32 = 66; +pub const SO_SNDTIMEO_NEW: u32 = 67; +pub const SO_DETACH_REUSEPORT_BPF: u32 = 68; +pub const SO_TIMESTAMP: u32 = 29; +pub const SO_TIMESTAMPNS: u32 = 35; +pub const SO_TIMESTAMPING: u32 = 37; +pub const SO_RCVTIMEO: u32 = 20; +pub const SO_SNDTIMEO: u32 = 21; +pub const SCM_TIMESTAMP: u32 = 29; +pub const SCM_TIMESTAMPNS: u32 = 35; +pub const SCM_TIMESTAMPING: u32 = 37; +pub const __osockaddr_defined: u32 = 1; +pub const IFNAMSIZ: u32 = 16; +pub const IFALIASZ: u32 = 256; +pub const ALTIFNAMSIZ: u32 = 128; +pub const GENERIC_HDLC_VERSION: u32 = 4; +pub const CLOCK_DEFAULT: u32 = 0; +pub const CLOCK_EXT: u32 = 1; +pub const CLOCK_INT: u32 = 2; +pub const CLOCK_TXINT: u32 = 3; +pub const CLOCK_TXFROMRX: u32 = 4; +pub const ENCODING_DEFAULT: u32 = 0; +pub const ENCODING_NRZ: u32 = 1; +pub const ENCODING_NRZI: u32 = 2; +pub const ENCODING_FM_MARK: u32 = 3; +pub const ENCODING_FM_SPACE: u32 = 4; +pub const ENCODING_MANCHESTER: u32 = 5; +pub const PARITY_DEFAULT: u32 = 0; +pub const PARITY_NONE: u32 = 1; +pub const PARITY_CRC16_PR0: u32 = 2; +pub const PARITY_CRC16_PR1: u32 = 3; +pub const PARITY_CRC16_PR0_CCITT: u32 = 4; +pub const PARITY_CRC16_PR1_CCITT: u32 = 5; +pub const PARITY_CRC32_PR0_CCITT: u32 = 6; +pub const PARITY_CRC32_PR1_CCITT: u32 = 7; +pub const LMI_DEFAULT: u32 = 0; +pub const LMI_NONE: u32 = 1; +pub const LMI_ANSI: u32 = 2; +pub const LMI_CCITT: u32 = 3; +pub const LMI_CISCO: u32 = 4; +pub const IF_GET_IFACE: u32 = 1; +pub const IF_GET_PROTO: u32 = 2; +pub const IF_IFACE_V35: u32 = 4096; +pub const IF_IFACE_V24: u32 = 4097; +pub const IF_IFACE_X21: u32 = 4098; +pub const IF_IFACE_T1: u32 = 4099; +pub const IF_IFACE_E1: u32 = 4100; +pub const IF_IFACE_SYNC_SERIAL: u32 = 4101; +pub const IF_IFACE_X21D: u32 = 4102; +pub const IF_PROTO_HDLC: u32 = 8192; +pub const IF_PROTO_PPP: u32 = 8193; +pub const IF_PROTO_CISCO: u32 = 8194; +pub const IF_PROTO_FR: u32 = 8195; +pub const IF_PROTO_FR_ADD_PVC: u32 = 8196; +pub const IF_PROTO_FR_DEL_PVC: u32 = 8197; +pub const IF_PROTO_X25: u32 = 8198; +pub const IF_PROTO_HDLC_ETH: u32 = 8199; +pub const IF_PROTO_FR_ADD_ETH_PVC: u32 = 8200; +pub const IF_PROTO_FR_DEL_ETH_PVC: u32 = 8201; +pub const IF_PROTO_FR_PVC: u32 = 8202; +pub const IF_PROTO_FR_ETH_PVC: u32 = 8203; +pub const IF_PROTO_RAW: u32 = 8204; +pub const IFHWADDRLEN: u32 = 6; +pub type __s8 = ::std::os::raw::c_schar; +pub type __u8 = ::std::os::raw::c_uchar; +pub type __s16 = ::std::os::raw::c_short; +pub type __u16 = ::std::os::raw::c_ushort; +pub type __s32 = ::std::os::raw::c_int; +pub type __u32 = ::std::os::raw::c_uint; +pub type __s64 = ::std::os::raw::c_longlong; +pub type __u64 = ::std::os::raw::c_ulonglong; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_fd_set { + pub fds_bits: [::std::os::raw::c_ulong; 16usize], +} +pub type __kernel_sighandler_t = + ::std::option::Option; +pub type __kernel_key_t = ::std::os::raw::c_int; +pub type __kernel_mqd_t = ::std::os::raw::c_int; +pub type __kernel_old_uid_t = ::std::os::raw::c_ushort; +pub type __kernel_old_gid_t = ::std::os::raw::c_ushort; +pub type __kernel_old_dev_t = ::std::os::raw::c_ulong; +pub type __kernel_long_t = ::std::os::raw::c_long; +pub type __kernel_ulong_t = ::std::os::raw::c_ulong; +pub type __kernel_ino_t = __kernel_ulong_t; +pub type __kernel_mode_t = ::std::os::raw::c_uint; +pub type __kernel_pid_t = ::std::os::raw::c_int; +pub type __kernel_ipc_pid_t = ::std::os::raw::c_int; +pub type __kernel_uid_t = ::std::os::raw::c_uint; +pub type __kernel_gid_t = ::std::os::raw::c_uint; +pub type __kernel_suseconds_t = __kernel_long_t; +pub type __kernel_daddr_t = ::std::os::raw::c_int; +pub type __kernel_uid32_t = ::std::os::raw::c_uint; +pub type __kernel_gid32_t = ::std::os::raw::c_uint; +pub type __kernel_size_t = __kernel_ulong_t; +pub type __kernel_ssize_t = __kernel_long_t; +pub type __kernel_ptrdiff_t = __kernel_long_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_fsid_t { + pub val: [::std::os::raw::c_int; 2usize], +} +pub type __kernel_off_t = __kernel_long_t; +pub type __kernel_loff_t = ::std::os::raw::c_longlong; +pub type __kernel_old_time_t = __kernel_long_t; +pub type __kernel_time_t = __kernel_long_t; +pub type __kernel_time64_t = ::std::os::raw::c_longlong; +pub type __kernel_clock_t = __kernel_long_t; +pub type __kernel_timer_t = ::std::os::raw::c_int; +pub type __kernel_clockid_t = ::std::os::raw::c_int; +pub type __kernel_caddr_t = *mut ::std::os::raw::c_char; +pub type __kernel_uid16_t = ::std::os::raw::c_ushort; +pub type __kernel_gid16_t = ::std::os::raw::c_ushort; +pub type __le16 = __u16; +pub type __be16 = __u16; +pub type __le32 = __u32; +pub type __be32 = __u32; +pub type __le64 = __u64; +pub type __be64 = __u64; +pub type __sum16 = __u16; +pub type __wsum = __u32; +pub type __poll_t = ::std::os::raw::c_uint; +pub type __kernel_sa_family_t = ::std::os::raw::c_ushort; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __kernel_sockaddr_storage { + pub __bindgen_anon_1: __kernel_sockaddr_storage__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union __kernel_sockaddr_storage__bindgen_ty_1 { + pub __bindgen_anon_1: __kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1, + pub __align: *mut ::std::os::raw::c_void, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1 { + pub ss_family: __kernel_sa_family_t, + pub __data: [::std::os::raw::c_char; 126usize], +} +pub type size_t = ::std::os::raw::c_ulong; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct iovec { + pub iov_base: *mut ::std::os::raw::c_void, + pub iov_len: size_t, +} +pub type __u_char = ::std::os::raw::c_uchar; +pub type __u_short = ::std::os::raw::c_ushort; +pub type __u_int = ::std::os::raw::c_uint; +pub type __u_long = ::std::os::raw::c_ulong; +pub type __int8_t = ::std::os::raw::c_schar; +pub type __uint8_t = ::std::os::raw::c_uchar; +pub type __int16_t = ::std::os::raw::c_short; +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_long; +pub type __uint64_t = ::std::os::raw::c_ulong; +pub type __int_least8_t = __int8_t; +pub type __uint_least8_t = __uint8_t; +pub type __int_least16_t = __int16_t; +pub type __uint_least16_t = __uint16_t; +pub type __int_least32_t = __int32_t; +pub type __uint_least32_t = __uint32_t; +pub type __int_least64_t = __int64_t; +pub type __uint_least64_t = __uint64_t; +pub type __quad_t = ::std::os::raw::c_long; +pub type __u_quad_t = ::std::os::raw::c_ulong; +pub type __intmax_t = ::std::os::raw::c_long; +pub type __uintmax_t = ::std::os::raw::c_ulong; +pub type __dev_t = ::std::os::raw::c_ulong; +pub type __uid_t = ::std::os::raw::c_uint; +pub type __gid_t = ::std::os::raw::c_uint; +pub type __ino_t = ::std::os::raw::c_ulong; +pub type __ino64_t = ::std::os::raw::c_ulong; +pub type __mode_t = ::std::os::raw::c_uint; +pub type __nlink_t = ::std::os::raw::c_ulong; +pub type __off_t = ::std::os::raw::c_long; +pub type __off64_t = ::std::os::raw::c_long; +pub type __pid_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __fsid_t { + pub __val: [::std::os::raw::c_int; 2usize], +} +pub type __clock_t = ::std::os::raw::c_long; +pub type __rlim_t = ::std::os::raw::c_ulong; +pub type __rlim64_t = ::std::os::raw::c_ulong; +pub type __id_t = ::std::os::raw::c_uint; +pub type __time_t = ::std::os::raw::c_long; +pub type __useconds_t = ::std::os::raw::c_uint; +pub type __suseconds_t = ::std::os::raw::c_long; +pub type __suseconds64_t = ::std::os::raw::c_long; +pub type __daddr_t = ::std::os::raw::c_int; +pub type __key_t = ::std::os::raw::c_int; +pub type __clockid_t = ::std::os::raw::c_int; +pub type __timer_t = *mut ::std::os::raw::c_void; +pub type __blksize_t = ::std::os::raw::c_long; +pub type __blkcnt_t = ::std::os::raw::c_long; +pub type __blkcnt64_t = ::std::os::raw::c_long; +pub type __fsblkcnt_t = ::std::os::raw::c_ulong; +pub type __fsblkcnt64_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt64_t = ::std::os::raw::c_ulong; +pub type __fsword_t = ::std::os::raw::c_long; +pub type __ssize_t = ::std::os::raw::c_long; +pub type __syscall_slong_t = ::std::os::raw::c_long; +pub type __syscall_ulong_t = ::std::os::raw::c_ulong; +pub type __loff_t = __off64_t; +pub type __caddr_t = *mut ::std::os::raw::c_char; +pub type __intptr_t = ::std::os::raw::c_long; +pub type __socklen_t = ::std::os::raw::c_uint; +pub type __sig_atomic_t = ::std::os::raw::c_int; +pub type u_char = __u_char; +pub type u_short = __u_short; +pub type u_int = __u_int; +pub type u_long = __u_long; +pub type quad_t = __quad_t; +pub type u_quad_t = __u_quad_t; +pub type fsid_t = __fsid_t; +pub type loff_t = __loff_t; +pub type ino_t = __ino_t; +pub type dev_t = __dev_t; +pub type gid_t = __gid_t; +pub type mode_t = __mode_t; +pub type nlink_t = __nlink_t; +pub type uid_t = __uid_t; +pub type off_t = __off_t; +pub type pid_t = __pid_t; +pub type id_t = __id_t; +pub type ssize_t = __ssize_t; +pub type daddr_t = __daddr_t; +pub type caddr_t = __caddr_t; +pub type key_t = __key_t; +pub type clock_t = __clock_t; +pub type clockid_t = __clockid_t; +pub type time_t = __time_t; +pub type timer_t = __timer_t; +pub type ulong = ::std::os::raw::c_ulong; +pub type ushort = ::std::os::raw::c_ushort; +pub type uint = ::std::os::raw::c_uint; +pub type u_int8_t = __uint8_t; +pub type u_int16_t = __uint16_t; +pub type u_int32_t = __uint32_t; +pub type u_int64_t = __uint64_t; +pub type register_t = ::std::os::raw::c_long; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sigset_t { + pub __val: [::std::os::raw::c_ulong; 16usize], +} +pub type sigset_t = __sigset_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timeval { + pub tv_sec: __time_t, + pub tv_usec: __suseconds_t, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timespec { + pub tv_sec: __time_t, + pub tv_nsec: __syscall_slong_t, +} +pub type suseconds_t = __suseconds_t; +pub type __fd_mask = ::std::os::raw::c_long; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct fd_set { + pub __fds_bits: [__fd_mask; 16usize], +} +pub type fd_mask = __fd_mask; +extern "C" { + pub fn select( + __nfds: ::std::os::raw::c_int, + __readfds: *mut fd_set, + __writefds: *mut fd_set, + __exceptfds: *mut fd_set, + __timeout: *mut timeval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn pselect( + __nfds: ::std::os::raw::c_int, + __readfds: *mut fd_set, + __writefds: *mut fd_set, + __exceptfds: *mut fd_set, + __timeout: *const timespec, + __sigmask: *const __sigset_t, + ) -> ::std::os::raw::c_int; +} +pub type blksize_t = __blksize_t; +pub type blkcnt_t = __blkcnt_t; +pub type fsblkcnt_t = __fsblkcnt_t; +pub type fsfilcnt_t = __fsfilcnt_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_internal_list { + pub __prev: *mut __pthread_internal_list, + pub __next: *mut __pthread_internal_list, +} +pub type __pthread_list_t = __pthread_internal_list; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_internal_slist { + pub __next: *mut __pthread_internal_slist, +} +pub type __pthread_slist_t = __pthread_internal_slist; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_mutex_s { + pub __lock: ::std::os::raw::c_int, + pub __count: ::std::os::raw::c_uint, + pub __owner: ::std::os::raw::c_int, + pub __nusers: ::std::os::raw::c_uint, + pub __kind: ::std::os::raw::c_int, + pub __spins: ::std::os::raw::c_short, + pub __elision: ::std::os::raw::c_short, + pub __list: __pthread_list_t, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_rwlock_arch_t { + pub __readers: ::std::os::raw::c_uint, + pub __writers: ::std::os::raw::c_uint, + pub __wrphase_futex: ::std::os::raw::c_uint, + pub __writers_futex: ::std::os::raw::c_uint, + pub __pad3: ::std::os::raw::c_uint, + pub __pad4: ::std::os::raw::c_uint, + pub __cur_writer: ::std::os::raw::c_int, + pub __shared: ::std::os::raw::c_int, + pub __rwelision: ::std::os::raw::c_schar, + pub __pad1: [::std::os::raw::c_uchar; 7usize], + pub __pad2: ::std::os::raw::c_ulong, + pub __flags: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __pthread_cond_s { + pub __bindgen_anon_1: __pthread_cond_s__bindgen_ty_1, + pub __bindgen_anon_2: __pthread_cond_s__bindgen_ty_2, + pub __g_refs: [::std::os::raw::c_uint; 2usize], + pub __g_size: [::std::os::raw::c_uint; 2usize], + pub __g1_orig_size: ::std::os::raw::c_uint, + pub __wrefs: ::std::os::raw::c_uint, + pub __g_signals: [::std::os::raw::c_uint; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union __pthread_cond_s__bindgen_ty_1 { + pub __wseq: ::std::os::raw::c_ulonglong, + pub __wseq32: __pthread_cond_s__bindgen_ty_1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_cond_s__bindgen_ty_1__bindgen_ty_1 { + pub __low: ::std::os::raw::c_uint, + pub __high: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union __pthread_cond_s__bindgen_ty_2 { + pub __g1_start: ::std::os::raw::c_ulonglong, + pub __g1_start32: __pthread_cond_s__bindgen_ty_2__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_cond_s__bindgen_ty_2__bindgen_ty_1 { + pub __low: ::std::os::raw::c_uint, + pub __high: ::std::os::raw::c_uint, +} +pub type __tss_t = ::std::os::raw::c_uint; +pub type __thrd_t = ::std::os::raw::c_ulong; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __once_flag { + pub __data: ::std::os::raw::c_int, +} +pub type pthread_t = ::std::os::raw::c_ulong; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_mutexattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_condattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, +} +pub type pthread_key_t = ::std::os::raw::c_uint; +pub type pthread_once_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_attr_t { + pub __size: [::std::os::raw::c_char; 56usize], + pub __align: ::std::os::raw::c_long, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_mutex_t { + pub __data: __pthread_mutex_s, + pub __size: [::std::os::raw::c_char; 40usize], + pub __align: ::std::os::raw::c_long, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_cond_t { + pub __data: __pthread_cond_s, + pub __size: [::std::os::raw::c_char; 48usize], + pub __align: ::std::os::raw::c_longlong, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_rwlock_t { + pub __data: __pthread_rwlock_arch_t, + pub __size: [::std::os::raw::c_char; 56usize], + pub __align: ::std::os::raw::c_long, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_rwlockattr_t { + pub __size: [::std::os::raw::c_char; 8usize], + pub __align: ::std::os::raw::c_long, +} +pub type pthread_spinlock_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_barrier_t { + pub __size: [::std::os::raw::c_char; 32usize], + pub __align: ::std::os::raw::c_long, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_barrierattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, +} +pub type socklen_t = __socklen_t; +pub const __socket_type_SOCK_STREAM: __socket_type = 1; +pub const __socket_type_SOCK_DGRAM: __socket_type = 2; +pub const __socket_type_SOCK_RAW: __socket_type = 3; +pub const __socket_type_SOCK_RDM: __socket_type = 4; +pub const __socket_type_SOCK_SEQPACKET: __socket_type = 5; +pub const __socket_type_SOCK_DCCP: __socket_type = 6; +pub const __socket_type_SOCK_PACKET: __socket_type = 10; +pub const __socket_type_SOCK_CLOEXEC: __socket_type = 524288; +pub const __socket_type_SOCK_NONBLOCK: __socket_type = 2048; +pub type __socket_type = ::std::os::raw::c_uint; +pub type sa_family_t = ::std::os::raw::c_ushort; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [::std::os::raw::c_uchar; 14usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sockaddr_storage { + pub ss_family: sa_family_t, + pub __ss_padding: [::std::os::raw::c_char; 118usize], + pub __ss_align: ::std::os::raw::c_ulong, +} +pub const MSG_OOB: ::std::os::raw::c_uint = 1; +pub const MSG_PEEK: ::std::os::raw::c_uint = 2; +pub const MSG_DONTROUTE: ::std::os::raw::c_uint = 4; +pub const MSG_CTRUNC: ::std::os::raw::c_uint = 8; +pub const MSG_PROXY: ::std::os::raw::c_uint = 16; +pub const MSG_TRUNC: ::std::os::raw::c_uint = 32; +pub const MSG_DONTWAIT: ::std::os::raw::c_uint = 64; +pub const MSG_EOR: ::std::os::raw::c_uint = 128; +pub const MSG_WAITALL: ::std::os::raw::c_uint = 256; +pub const MSG_FIN: ::std::os::raw::c_uint = 512; +pub const MSG_SYN: ::std::os::raw::c_uint = 1024; +pub const MSG_CONFIRM: ::std::os::raw::c_uint = 2048; +pub const MSG_RST: ::std::os::raw::c_uint = 4096; +pub const MSG_ERRQUEUE: ::std::os::raw::c_uint = 8192; +pub const MSG_NOSIGNAL: ::std::os::raw::c_uint = 16384; +pub const MSG_MORE: ::std::os::raw::c_uint = 32768; +pub const MSG_WAITFORONE: ::std::os::raw::c_uint = 65536; +pub const MSG_BATCH: ::std::os::raw::c_uint = 262144; +pub const MSG_ZEROCOPY: ::std::os::raw::c_uint = 67108864; +pub const MSG_FASTOPEN: ::std::os::raw::c_uint = 536870912; +pub const MSG_CMSG_CLOEXEC: ::std::os::raw::c_uint = 1073741824; +pub type _bindgen_ty_1 = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct msghdr { + pub msg_name: *mut ::std::os::raw::c_void, + pub msg_namelen: socklen_t, + pub msg_iov: *mut iovec, + pub msg_iovlen: size_t, + pub msg_control: *mut ::std::os::raw::c_void, + pub msg_controllen: size_t, + pub msg_flags: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug)] +pub struct cmsghdr { + pub cmsg_len: size_t, + pub cmsg_level: ::std::os::raw::c_int, + pub cmsg_type: ::std::os::raw::c_int, + pub __cmsg_data: __IncompleteArrayField<::std::os::raw::c_uchar>, +} +extern "C" { + pub fn __cmsg_nxthdr(__mhdr: *mut msghdr, __cmsg: *mut cmsghdr) -> *mut cmsghdr; +} +pub const SCM_RIGHTS: ::std::os::raw::c_uint = 1; +pub type _bindgen_ty_2 = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct linger { + pub l_onoff: ::std::os::raw::c_int, + pub l_linger: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct osockaddr { + pub sa_family: ::std::os::raw::c_ushort, + pub sa_data: [::std::os::raw::c_uchar; 14usize], +} +pub const SHUT_RD: ::std::os::raw::c_uint = 0; +pub const SHUT_WR: ::std::os::raw::c_uint = 1; +pub const SHUT_RDWR: ::std::os::raw::c_uint = 2; +pub type _bindgen_ty_3 = ::std::os::raw::c_uint; +extern "C" { + pub fn socket( + __domain: ::std::os::raw::c_int, + __type: ::std::os::raw::c_int, + __protocol: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn socketpair( + __domain: ::std::os::raw::c_int, + __type: ::std::os::raw::c_int, + __protocol: ::std::os::raw::c_int, + __fds: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn bind( + __fd: ::std::os::raw::c_int, + __addr: *const sockaddr, + __len: socklen_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getsockname( + __fd: ::std::os::raw::c_int, + __addr: *mut sockaddr, + __len: *mut socklen_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn connect( + __fd: ::std::os::raw::c_int, + __addr: *const sockaddr, + __len: socklen_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getpeername( + __fd: ::std::os::raw::c_int, + __addr: *mut sockaddr, + __len: *mut socklen_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn send( + __fd: ::std::os::raw::c_int, + __buf: *const ::std::os::raw::c_void, + __n: size_t, + __flags: ::std::os::raw::c_int, + ) -> ssize_t; +} +extern "C" { + pub fn recv( + __fd: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_void, + __n: size_t, + __flags: ::std::os::raw::c_int, + ) -> ssize_t; +} +extern "C" { + pub fn sendto( + __fd: ::std::os::raw::c_int, + __buf: *const ::std::os::raw::c_void, + __n: size_t, + __flags: ::std::os::raw::c_int, + __addr: *const sockaddr, + __addr_len: socklen_t, + ) -> ssize_t; +} +extern "C" { + pub fn recvfrom( + __fd: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_void, + __n: size_t, + __flags: ::std::os::raw::c_int, + __addr: *mut sockaddr, + __addr_len: *mut socklen_t, + ) -> ssize_t; +} +extern "C" { + pub fn sendmsg( + __fd: ::std::os::raw::c_int, + __message: *const msghdr, + __flags: ::std::os::raw::c_int, + ) -> ssize_t; +} +extern "C" { + pub fn recvmsg( + __fd: ::std::os::raw::c_int, + __message: *mut msghdr, + __flags: ::std::os::raw::c_int, + ) -> ssize_t; +} +extern "C" { + pub fn getsockopt( + __fd: ::std::os::raw::c_int, + __level: ::std::os::raw::c_int, + __optname: ::std::os::raw::c_int, + __optval: *mut ::std::os::raw::c_void, + __optlen: *mut socklen_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setsockopt( + __fd: ::std::os::raw::c_int, + __level: ::std::os::raw::c_int, + __optname: ::std::os::raw::c_int, + __optval: *const ::std::os::raw::c_void, + __optlen: socklen_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn listen(__fd: ::std::os::raw::c_int, __n: ::std::os::raw::c_int) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn accept( + __fd: ::std::os::raw::c_int, + __addr: *mut sockaddr, + __addr_len: *mut socklen_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn shutdown( + __fd: ::std::os::raw::c_int, + __how: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sockatmark(__fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isfdtype( + __fd: ::std::os::raw::c_int, + __fdtype: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sync_serial_settings { + pub clock_rate: ::std::os::raw::c_uint, + pub clock_type: ::std::os::raw::c_uint, + pub loopback: ::std::os::raw::c_ushort, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct te1_settings { + pub clock_rate: ::std::os::raw::c_uint, + pub clock_type: ::std::os::raw::c_uint, + pub loopback: ::std::os::raw::c_ushort, + pub slot_map: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct raw_hdlc_proto { + pub encoding: ::std::os::raw::c_ushort, + pub parity: ::std::os::raw::c_ushort, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct fr_proto { + pub t391: ::std::os::raw::c_uint, + pub t392: ::std::os::raw::c_uint, + pub n391: ::std::os::raw::c_uint, + pub n392: ::std::os::raw::c_uint, + pub n393: ::std::os::raw::c_uint, + pub lmi: ::std::os::raw::c_ushort, + pub dce: ::std::os::raw::c_ushort, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct fr_proto_pvc { + pub dlci: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct fr_proto_pvc_info { + pub dlci: ::std::os::raw::c_uint, + pub master: [::std::os::raw::c_char; 16usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct cisco_proto { + pub interval: ::std::os::raw::c_uint, + pub timeout: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct x25_hdlc_proto { + pub dce: ::std::os::raw::c_ushort, + pub modulo: ::std::os::raw::c_uint, + pub window: ::std::os::raw::c_uint, + pub t1: ::std::os::raw::c_uint, + pub t2: ::std::os::raw::c_uint, + pub n2: ::std::os::raw::c_uint, +} +pub const net_device_flags_IFF_UP: net_device_flags = 1; +pub const net_device_flags_IFF_BROADCAST: net_device_flags = 2; +pub const net_device_flags_IFF_DEBUG: net_device_flags = 4; +pub const net_device_flags_IFF_LOOPBACK: net_device_flags = 8; +pub const net_device_flags_IFF_POINTOPOINT: net_device_flags = 16; +pub const net_device_flags_IFF_NOTRAILERS: net_device_flags = 32; +pub const net_device_flags_IFF_RUNNING: net_device_flags = 64; +pub const net_device_flags_IFF_NOARP: net_device_flags = 128; +pub const net_device_flags_IFF_PROMISC: net_device_flags = 256; +pub const net_device_flags_IFF_ALLMULTI: net_device_flags = 512; +pub const net_device_flags_IFF_MASTER: net_device_flags = 1024; +pub const net_device_flags_IFF_SLAVE: net_device_flags = 2048; +pub const net_device_flags_IFF_MULTICAST: net_device_flags = 4096; +pub const net_device_flags_IFF_PORTSEL: net_device_flags = 8192; +pub const net_device_flags_IFF_AUTOMEDIA: net_device_flags = 16384; +pub const net_device_flags_IFF_DYNAMIC: net_device_flags = 32768; +pub const net_device_flags_IFF_LOWER_UP: net_device_flags = 65536; +pub const net_device_flags_IFF_DORMANT: net_device_flags = 131072; +pub const net_device_flags_IFF_ECHO: net_device_flags = 262144; +#[doc = " enum net_device_flags - &struct net_device flags"] +#[doc = ""] +#[doc = " These are the &struct net_device flags, they can be set by drivers, the"] +#[doc = " kernel and some can be triggered by userspace. Userspace can query and"] +#[doc = " set these flags using userspace utilities but there is also a sysfs"] +#[doc = " entry available for all dev flags which can be queried and set. These flags"] +#[doc = " are shared for all types of net_devices. The sysfs entries are available"] +#[doc = " via /sys/class/net//flags. Flags which can be toggled through sysfs"] +#[doc = " are annotated below, note that only a few flags can be toggled and some"] +#[doc = " other flags are always preserved from the original net_device flags"] +#[doc = " even if you try to set them via sysfs. Flags which are always preserved"] +#[doc = " are kept under the flag grouping @IFF_VOLATILE. Flags which are __volatile__"] +#[doc = " are annotated below as such."] +#[doc = ""] +#[doc = " You should have a pretty good reason to be extending these flags."] +#[doc = ""] +#[doc = " @IFF_UP: interface is up. Can be toggled through sysfs."] +#[doc = " @IFF_BROADCAST: broadcast address valid. Volatile."] +#[doc = " @IFF_DEBUG: turn on debugging. Can be toggled through sysfs."] +#[doc = " @IFF_LOOPBACK: is a loopback net. Volatile."] +#[doc = " @IFF_POINTOPOINT: interface is has p-p link. Volatile."] +#[doc = " @IFF_NOTRAILERS: avoid use of trailers. Can be toggled through sysfs."] +#[doc = "\tVolatile."] +#[doc = " @IFF_RUNNING: interface RFC2863 OPER_UP. Volatile."] +#[doc = " @IFF_NOARP: no ARP protocol. Can be toggled through sysfs. Volatile."] +#[doc = " @IFF_PROMISC: receive all packets. Can be toggled through sysfs."] +#[doc = " @IFF_ALLMULTI: receive all multicast packets. Can be toggled through"] +#[doc = "\tsysfs."] +#[doc = " @IFF_MASTER: master of a load balancer. Volatile."] +#[doc = " @IFF_SLAVE: slave of a load balancer. Volatile."] +#[doc = " @IFF_MULTICAST: Supports multicast. Can be toggled through sysfs."] +#[doc = " @IFF_PORTSEL: can set media type. Can be toggled through sysfs."] +#[doc = " @IFF_AUTOMEDIA: auto media select active. Can be toggled through sysfs."] +#[doc = " @IFF_DYNAMIC: dialup device with changing addresses. Can be toggled"] +#[doc = "\tthrough sysfs."] +#[doc = " @IFF_LOWER_UP: driver signals L1 up. Volatile."] +#[doc = " @IFF_DORMANT: driver signals dormant. Volatile."] +#[doc = " @IFF_ECHO: echo sent packets. Volatile."] +pub type net_device_flags = ::std::os::raw::c_uint; +pub const IF_OPER_UNKNOWN: ::std::os::raw::c_uint = 0; +pub const IF_OPER_NOTPRESENT: ::std::os::raw::c_uint = 1; +pub const IF_OPER_DOWN: ::std::os::raw::c_uint = 2; +pub const IF_OPER_LOWERLAYERDOWN: ::std::os::raw::c_uint = 3; +pub const IF_OPER_TESTING: ::std::os::raw::c_uint = 4; +pub const IF_OPER_DORMANT: ::std::os::raw::c_uint = 5; +pub const IF_OPER_UP: ::std::os::raw::c_uint = 6; +pub type _bindgen_ty_4 = ::std::os::raw::c_uint; +pub const IF_LINK_MODE_DEFAULT: ::std::os::raw::c_uint = 0; +pub const IF_LINK_MODE_DORMANT: ::std::os::raw::c_uint = 1; +pub const IF_LINK_MODE_TESTING: ::std::os::raw::c_uint = 2; +pub type _bindgen_ty_5 = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ifmap { + pub mem_start: ::std::os::raw::c_ulong, + pub mem_end: ::std::os::raw::c_ulong, + pub base_addr: ::std::os::raw::c_ushort, + pub irq: ::std::os::raw::c_uchar, + pub dma: ::std::os::raw::c_uchar, + pub port: ::std::os::raw::c_uchar, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct if_settings { + pub type_: ::std::os::raw::c_uint, + pub size: ::std::os::raw::c_uint, + pub ifs_ifsu: if_settings__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union if_settings__bindgen_ty_1 { + pub raw_hdlc: *mut raw_hdlc_proto, + pub cisco: *mut cisco_proto, + pub fr: *mut fr_proto, + pub fr_pvc: *mut fr_proto_pvc, + pub fr_pvc_info: *mut fr_proto_pvc_info, + pub x25: *mut x25_hdlc_proto, + pub sync: *mut sync_serial_settings, + pub te1: *mut te1_settings, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ifreq { + pub ifr_ifrn: ifreq__bindgen_ty_1, + pub ifr_ifru: ifreq__bindgen_ty_2, +} + +impl Default for ifreq { + fn default() -> Self { + // SAFETY: all zeros is a valid pattern for this data type + unsafe { std::mem::zeroed() } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union ifreq__bindgen_ty_1 { + pub ifrn_name: [::std::os::raw::c_uchar; 16usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union ifreq__bindgen_ty_2 { + pub ifru_addr: sockaddr, + pub ifru_dstaddr: sockaddr, + pub ifru_broadaddr: sockaddr, + pub ifru_netmask: sockaddr, + pub ifru_hwaddr: sockaddr, + pub ifru_flags: ::std::os::raw::c_short, + pub ifru_ivalue: ::std::os::raw::c_int, + pub ifru_mtu: ::std::os::raw::c_int, + pub ifru_map: ifmap, + pub ifru_slave: [::std::os::raw::c_uchar; 16usize], + pub ifru_newname: [::std::os::raw::c_uchar; 16usize], + pub ifru_data: *mut ::std::os::raw::c_void, + pub ifru_settings: if_settings, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ifconf { + pub ifc_len: ::std::os::raw::c_int, + pub ifc_ifcu: ifconf__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union ifconf__bindgen_ty_1 { + pub ifcu_buf: *mut ::std::os::raw::c_char, + pub ifcu_req: *mut ifreq, +} diff --git a/src/vmm/src/core/network/net_gen/inn.rs b/src/vmm/src/core/network/net_gen/inn.rs new file mode 100644 index 0000000..d21e05e --- /dev/null +++ b/src/vmm/src/core/network/net_gen/inn.rs @@ -0,0 +1,299 @@ +// Copyright © 2021 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 + +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] + +// bindgen /usr/include/linux/in.h --no-layout-tests + +/* automatically generated by rust-bindgen 0.58.1 */ + +pub const __BITS_PER_LONG: u32 = 64; +pub const __FD_SETSIZE: u32 = 1024; +pub const __UAPI_DEF_IF_IFCONF: u32 = 1; +pub const __UAPI_DEF_IF_IFMAP: u32 = 1; +pub const __UAPI_DEF_IF_IFNAMSIZ: u32 = 1; +pub const __UAPI_DEF_IF_IFREQ: u32 = 1; +pub const __UAPI_DEF_IF_NET_DEVICE_FLAGS: u32 = 1; +pub const __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO: u32 = 1; +pub const __UAPI_DEF_IN_ADDR: u32 = 1; +pub const __UAPI_DEF_IN_IPPROTO: u32 = 1; +pub const __UAPI_DEF_IN_PKTINFO: u32 = 1; +pub const __UAPI_DEF_IP_MREQ: u32 = 1; +pub const __UAPI_DEF_SOCKADDR_IN: u32 = 1; +pub const __UAPI_DEF_IN_CLASS: u32 = 1; +pub const __UAPI_DEF_IN6_ADDR: u32 = 1; +pub const __UAPI_DEF_IN6_ADDR_ALT: u32 = 1; +pub const __UAPI_DEF_SOCKADDR_IN6: u32 = 1; +pub const __UAPI_DEF_IPV6_MREQ: u32 = 1; +pub const __UAPI_DEF_IPPROTO_V6: u32 = 1; +pub const __UAPI_DEF_IPV6_OPTIONS: u32 = 1; +pub const __UAPI_DEF_IN6_PKTINFO: u32 = 1; +pub const __UAPI_DEF_IP6_MTUINFO: u32 = 1; +pub const __UAPI_DEF_SOCKADDR_IPX: u32 = 1; +pub const __UAPI_DEF_IPX_ROUTE_DEFINITION: u32 = 1; +pub const __UAPI_DEF_IPX_INTERFACE_DEFINITION: u32 = 1; +pub const __UAPI_DEF_IPX_CONFIG_DATA: u32 = 1; +pub const __UAPI_DEF_IPX_ROUTE_DEF: u32 = 1; +pub const __UAPI_DEF_XATTR: u32 = 1; +pub const _K_SS_MAXSIZE: u32 = 128; +pub const IP_TOS: u32 = 1; +pub const IP_TTL: u32 = 2; +pub const IP_HDRINCL: u32 = 3; +pub const IP_OPTIONS: u32 = 4; +pub const IP_ROUTER_ALERT: u32 = 5; +pub const IP_RECVOPTS: u32 = 6; +pub const IP_RETOPTS: u32 = 7; +pub const IP_PKTINFO: u32 = 8; +pub const IP_PKTOPTIONS: u32 = 9; +pub const IP_MTU_DISCOVER: u32 = 10; +pub const IP_RECVERR: u32 = 11; +pub const IP_RECVTTL: u32 = 12; +pub const IP_RECVTOS: u32 = 13; +pub const IP_MTU: u32 = 14; +pub const IP_FREEBIND: u32 = 15; +pub const IP_IPSEC_POLICY: u32 = 16; +pub const IP_XFRM_POLICY: u32 = 17; +pub const IP_PASSSEC: u32 = 18; +pub const IP_TRANSPARENT: u32 = 19; +pub const IP_RECVRETOPTS: u32 = 7; +pub const IP_ORIGDSTADDR: u32 = 20; +pub const IP_RECVORIGDSTADDR: u32 = 20; +pub const IP_MINTTL: u32 = 21; +pub const IP_NODEFRAG: u32 = 22; +pub const IP_CHECKSUM: u32 = 23; +pub const IP_BIND_ADDRESS_NO_PORT: u32 = 24; +pub const IP_RECVFRAGSIZE: u32 = 25; +pub const IP_PMTUDISC_DONT: u32 = 0; +pub const IP_PMTUDISC_WANT: u32 = 1; +pub const IP_PMTUDISC_DO: u32 = 2; +pub const IP_PMTUDISC_PROBE: u32 = 3; +pub const IP_PMTUDISC_INTERFACE: u32 = 4; +pub const IP_PMTUDISC_OMIT: u32 = 5; +pub const IP_MULTICAST_IF: u32 = 32; +pub const IP_MULTICAST_TTL: u32 = 33; +pub const IP_MULTICAST_LOOP: u32 = 34; +pub const IP_ADD_MEMBERSHIP: u32 = 35; +pub const IP_DROP_MEMBERSHIP: u32 = 36; +pub const IP_UNBLOCK_SOURCE: u32 = 37; +pub const IP_BLOCK_SOURCE: u32 = 38; +pub const IP_ADD_SOURCE_MEMBERSHIP: u32 = 39; +pub const IP_DROP_SOURCE_MEMBERSHIP: u32 = 40; +pub const IP_MSFILTER: u32 = 41; +pub const MCAST_JOIN_GROUP: u32 = 42; +pub const MCAST_BLOCK_SOURCE: u32 = 43; +pub const MCAST_UNBLOCK_SOURCE: u32 = 44; +pub const MCAST_LEAVE_GROUP: u32 = 45; +pub const MCAST_JOIN_SOURCE_GROUP: u32 = 46; +pub const MCAST_LEAVE_SOURCE_GROUP: u32 = 47; +pub const MCAST_MSFILTER: u32 = 48; +pub const IP_MULTICAST_ALL: u32 = 49; +pub const IP_UNICAST_IF: u32 = 50; +pub const MCAST_EXCLUDE: u32 = 0; +pub const MCAST_INCLUDE: u32 = 1; +pub const IP_DEFAULT_MULTICAST_TTL: u32 = 1; +pub const IP_DEFAULT_MULTICAST_LOOP: u32 = 1; +pub const __SOCK_SIZE__: u32 = 16; +pub const IN_CLASSA_NET: u32 = 4278190080; +pub const IN_CLASSA_NSHIFT: u32 = 24; +pub const IN_CLASSA_HOST: u32 = 16777215; +pub const IN_CLASSA_MAX: u32 = 128; +pub const IN_CLASSB_NET: u32 = 4294901760; +pub const IN_CLASSB_NSHIFT: u32 = 16; +pub const IN_CLASSB_HOST: u32 = 65535; +pub const IN_CLASSB_MAX: u32 = 65536; +pub const IN_CLASSC_NET: u32 = 4294967040; +pub const IN_CLASSC_NSHIFT: u32 = 8; +pub const IN_CLASSC_HOST: u32 = 255; +pub const IN_MULTICAST_NET: u32 = 3758096384; +pub const IN_CLASSE_NET: u32 = 4294967295; +pub const IN_CLASSE_NSHIFT: u32 = 0; +pub const IN_LOOPBACKNET: u32 = 127; +pub const INADDR_LOOPBACK: u32 = 2130706433; +pub const INADDR_UNSPEC_GROUP: u32 = 3758096384; +pub const INADDR_ALLHOSTS_GROUP: u32 = 3758096385; +pub const INADDR_ALLRTRS_GROUP: u32 = 3758096386; +pub const INADDR_ALLSNOOPERS_GROUP: u32 = 3758096490; +pub const INADDR_MAX_LOCAL_GROUP: u32 = 3758096639; +pub const __LITTLE_ENDIAN: u32 = 1234; +pub type __s8 = ::std::os::raw::c_schar; +pub type __u8 = ::std::os::raw::c_uchar; +pub type __s16 = ::std::os::raw::c_short; +pub type __u16 = ::std::os::raw::c_ushort; +pub type __s32 = ::std::os::raw::c_int; +pub type __u32 = ::std::os::raw::c_uint; +pub type __s64 = ::std::os::raw::c_longlong; +pub type __u64 = ::std::os::raw::c_ulonglong; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_fd_set { + pub fds_bits: [::std::os::raw::c_ulong; 16usize], +} +pub type __kernel_sighandler_t = + ::std::option::Option; +pub type __kernel_key_t = ::std::os::raw::c_int; +pub type __kernel_mqd_t = ::std::os::raw::c_int; +pub type __kernel_old_uid_t = ::std::os::raw::c_ushort; +pub type __kernel_old_gid_t = ::std::os::raw::c_ushort; +pub type __kernel_old_dev_t = ::std::os::raw::c_ulong; +pub type __kernel_long_t = ::std::os::raw::c_long; +pub type __kernel_ulong_t = ::std::os::raw::c_ulong; +pub type __kernel_ino_t = __kernel_ulong_t; +pub type __kernel_mode_t = ::std::os::raw::c_uint; +pub type __kernel_pid_t = ::std::os::raw::c_int; +pub type __kernel_ipc_pid_t = ::std::os::raw::c_int; +pub type __kernel_uid_t = ::std::os::raw::c_uint; +pub type __kernel_gid_t = ::std::os::raw::c_uint; +pub type __kernel_suseconds_t = __kernel_long_t; +pub type __kernel_daddr_t = ::std::os::raw::c_int; +pub type __kernel_uid32_t = ::std::os::raw::c_uint; +pub type __kernel_gid32_t = ::std::os::raw::c_uint; +pub type __kernel_size_t = __kernel_ulong_t; +pub type __kernel_ssize_t = __kernel_long_t; +pub type __kernel_ptrdiff_t = __kernel_long_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_fsid_t { + pub val: [::std::os::raw::c_int; 2usize], +} +pub type __kernel_off_t = __kernel_long_t; +pub type __kernel_loff_t = ::std::os::raw::c_longlong; +pub type __kernel_old_time_t = __kernel_long_t; +pub type __kernel_time_t = __kernel_long_t; +pub type __kernel_time64_t = ::std::os::raw::c_longlong; +pub type __kernel_clock_t = __kernel_long_t; +pub type __kernel_timer_t = ::std::os::raw::c_int; +pub type __kernel_clockid_t = ::std::os::raw::c_int; +pub type __kernel_caddr_t = *mut ::std::os::raw::c_char; +pub type __kernel_uid16_t = ::std::os::raw::c_ushort; +pub type __kernel_gid16_t = ::std::os::raw::c_ushort; +pub type __le16 = __u16; +pub type __be16 = __u16; +pub type __le32 = __u32; +pub type __be32 = __u32; +pub type __le64 = __u64; +pub type __be64 = __u64; +pub type __sum16 = __u16; +pub type __wsum = __u32; +pub type __poll_t = ::std::os::raw::c_uint; +pub type __kernel_sa_family_t = ::std::os::raw::c_ushort; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __kernel_sockaddr_storage { + pub __bindgen_anon_1: __kernel_sockaddr_storage__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union __kernel_sockaddr_storage__bindgen_ty_1 { + pub __bindgen_anon_1: __kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1, + pub __align: *mut ::std::os::raw::c_void, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1 { + pub ss_family: __kernel_sa_family_t, + pub __data: [::std::os::raw::c_char; 126usize], +} +pub const IPPROTO_IP: ::std::os::raw::c_uint = 0; +pub const IPPROTO_ICMP: ::std::os::raw::c_uint = 1; +pub const IPPROTO_IGMP: ::std::os::raw::c_uint = 2; +pub const IPPROTO_IPIP: ::std::os::raw::c_uint = 4; +pub const IPPROTO_TCP: ::std::os::raw::c_uint = 6; +pub const IPPROTO_EGP: ::std::os::raw::c_uint = 8; +pub const IPPROTO_PUP: ::std::os::raw::c_uint = 12; +pub const IPPROTO_UDP: ::std::os::raw::c_uint = 17; +pub const IPPROTO_IDP: ::std::os::raw::c_uint = 22; +pub const IPPROTO_TP: ::std::os::raw::c_uint = 29; +pub const IPPROTO_DCCP: ::std::os::raw::c_uint = 33; +pub const IPPROTO_IPV6: ::std::os::raw::c_uint = 41; +pub const IPPROTO_RSVP: ::std::os::raw::c_uint = 46; +pub const IPPROTO_GRE: ::std::os::raw::c_uint = 47; +pub const IPPROTO_ESP: ::std::os::raw::c_uint = 50; +pub const IPPROTO_AH: ::std::os::raw::c_uint = 51; +pub const IPPROTO_MTP: ::std::os::raw::c_uint = 92; +pub const IPPROTO_BEETPH: ::std::os::raw::c_uint = 94; +pub const IPPROTO_ENCAP: ::std::os::raw::c_uint = 98; +pub const IPPROTO_PIM: ::std::os::raw::c_uint = 103; +pub const IPPROTO_COMP: ::std::os::raw::c_uint = 108; +pub const IPPROTO_SCTP: ::std::os::raw::c_uint = 132; +pub const IPPROTO_UDPLITE: ::std::os::raw::c_uint = 136; +pub const IPPROTO_MPLS: ::std::os::raw::c_uint = 137; +pub const IPPROTO_ETHERNET: ::std::os::raw::c_uint = 143; +pub const IPPROTO_RAW: ::std::os::raw::c_uint = 255; +pub const IPPROTO_MPTCP: ::std::os::raw::c_uint = 262; +pub const IPPROTO_MAX: ::std::os::raw::c_uint = 263; +pub type _bindgen_ty_1 = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct in_addr { + pub s_addr: __be32, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ip_mreqn { + pub imr_multiaddr: in_addr, + pub imr_address: in_addr, + pub imr_ifindex: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ip_mreq_source { + pub imr_multiaddr: __be32, + pub imr_interface: __be32, + pub imr_sourceaddr: __be32, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ip_msfilter { + pub imsf_multiaddr: __be32, + pub imsf_interface: __be32, + pub imsf_fmode: __u32, + pub imsf_numsrc: __u32, + pub imsf_slist: [__be32; 1usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct group_req { + pub gr_interface: __u32, + pub gr_group: __kernel_sockaddr_storage, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct group_source_req { + pub gsr_interface: __u32, + pub gsr_group: __kernel_sockaddr_storage, + pub gsr_source: __kernel_sockaddr_storage, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct group_filter { + pub gf_interface: __u32, + pub gf_group: __kernel_sockaddr_storage, + pub gf_fmode: __u32, + pub gf_numsrc: __u32, + pub gf_slist: [__kernel_sockaddr_storage; 1usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct in_pktinfo { + pub ipi_ifindex: ::std::os::raw::c_int, + pub ipi_spec_dst: in_addr, + pub ipi_addr: in_addr, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sockaddr_in { + pub sin_family: __kernel_sa_family_t, + pub sin_port: __be16, + pub sin_addr: in_addr, + pub __pad: [::std::os::raw::c_uchar; 8usize], +} diff --git a/src/vmm/src/core/network/net_gen/mod.rs b/src/vmm/src/core/network/net_gen/mod.rs new file mode 100644 index 0000000..a9cd772 --- /dev/null +++ b/src/vmm/src/core/network/net_gen/mod.rs @@ -0,0 +1,59 @@ +// Copyright TUNTAP, 2017 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the THIRD-PARTY file. + +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +// generated with bindgen /usr/include/linux/if.h --no-unstable-rust +// --constified-enum '*' --with-derive-default -- -D __UAPI_DEF_IF_IFNAMSIZ -D +// __UAPI_DEF_IF_NET_DEVICE_FLAGS -D __UAPI_DEF_IF_IFREQ -D __UAPI_DEF_IF_IFMAP +// Name is "iff" to avoid conflicting with "if" keyword. +// Generated against Linux 4.11 to include fix "uapi: fix linux/if.h userspace +// compilation errors". +// Manual fixup of ifrn_name to be of type c_uchar instead of c_char. +pub mod iff; +// generated with bindgen /usr/include/linux/if_tun.h --no-unstable-rust +// --constified-enum '*' --with-derive-default +pub mod if_tun; +// generated with bindgen /usr/include/linux/in.h --no-unstable-rust +// --constified-enum '*' --with-derive-default +// Name is "inn" to avoid conflicting with "in" keyword. +pub mod inn; +// generated with bindgen /usr/include/linux/sockios.h --no-unstable-rust +// --constified-enum '*' --with-derive-default +pub mod sockios; +pub use if_tun::{sock_fprog, IFF_MULTI_QUEUE, IFF_NO_PI, IFF_TAP, IFF_VNET_HDR}; +pub use iff::{ifreq, net_device_flags_IFF_UP, sockaddr, AF_INET}; +pub use inn::sockaddr_in; +use vmm_sys_util::ioctl_ioc_nr; +use vmm_sys_util::ioctl_ior_nr; +use vmm_sys_util::ioctl_iow_nr; + +pub const TUNTAP: ::std::os::raw::c_uint = 84; + +ioctl_iow_nr!(TUNSETNOCSUM, TUNTAP, 200, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNSETDEBUG, TUNTAP, 201, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNSETIFF, TUNTAP, 202, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNSETPERSIST, TUNTAP, 203, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNSETOWNER, TUNTAP, 204, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNSETLINK, TUNTAP, 205, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNSETGROUP, TUNTAP, 206, ::std::os::raw::c_int); +ioctl_ior_nr!(TUNGETFEATURES, TUNTAP, 207, ::std::os::raw::c_uint); +ioctl_iow_nr!(TUNSETOFFLOAD, TUNTAP, 208, ::std::os::raw::c_uint); +ioctl_iow_nr!(TUNSETTXFILTER, TUNTAP, 209, ::std::os::raw::c_uint); +ioctl_ior_nr!(TUNGETIFF, TUNTAP, 210, ::std::os::raw::c_uint); +ioctl_ior_nr!(TUNGETSNDBUF, TUNTAP, 211, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNSETSNDBUF, TUNTAP, 212, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNATTACHFILTER, TUNTAP, 213, sock_fprog); +ioctl_iow_nr!(TUNDETACHFILTER, TUNTAP, 214, sock_fprog); +ioctl_ior_nr!(TUNGETVNETHDRSZ, TUNTAP, 215, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNSETVNETHDRSZ, TUNTAP, 216, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNSETQUEUE, TUNTAP, 217, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNSETIFINDEX, TUNTAP, 218, ::std::os::raw::c_uint); +ioctl_ior_nr!(TUNGETFILTER, TUNTAP, 219, sock_fprog); +ioctl_iow_nr!(TUNSETVNETLE, TUNTAP, 220, ::std::os::raw::c_int); +ioctl_ior_nr!(TUNGETVNETLE, TUNTAP, 221, ::std::os::raw::c_int); +ioctl_iow_nr!(TUNSETVNETBE, TUNTAP, 222, ::std::os::raw::c_int); +ioctl_ior_nr!(TUNGETVNETBE, TUNTAP, 223, ::std::os::raw::c_int); diff --git a/src/vmm/src/core/network/net_gen/sockios.rs b/src/vmm/src/core/network/net_gen/sockios.rs new file mode 100644 index 0000000..684eedc --- /dev/null +++ b/src/vmm/src/core/network/net_gen/sockios.rs @@ -0,0 +1,100 @@ +// Copyright © 2021 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] + +// bindgen /usr/include/linux/sockios.h --no-layout-tests + +/* automatically generated by rust-bindgen 0.58.1 */ + +pub const __BITS_PER_LONG: u32 = 64; +pub const FIOSETOWN: u32 = 35073; +pub const SIOCSPGRP: u32 = 35074; +pub const FIOGETOWN: u32 = 35075; +pub const SIOCGPGRP: u32 = 35076; +pub const SIOCATMARK: u32 = 35077; +pub const SIOCGSTAMP_OLD: u32 = 35078; +pub const SIOCGSTAMPNS_OLD: u32 = 35079; +pub const SOCK_IOC_TYPE: u32 = 137; +pub const SIOCGSTAMP: u32 = 35078; +pub const SIOCGSTAMPNS: u32 = 35079; +pub const SIOCADDRT: u32 = 35083; +pub const SIOCDELRT: u32 = 35084; +pub const SIOCRTMSG: u32 = 35085; +pub const SIOCGIFNAME: u32 = 35088; +pub const SIOCSIFLINK: u32 = 35089; +pub const SIOCGIFCONF: u32 = 35090; +pub const SIOCGIFFLAGS: u32 = 35091; +pub const SIOCSIFFLAGS: u32 = 35092; +pub const SIOCGIFADDR: u32 = 35093; +pub const SIOCSIFADDR: u32 = 35094; +pub const SIOCGIFDSTADDR: u32 = 35095; +pub const SIOCSIFDSTADDR: u32 = 35096; +pub const SIOCGIFBRDADDR: u32 = 35097; +pub const SIOCSIFBRDADDR: u32 = 35098; +pub const SIOCGIFNETMASK: u32 = 35099; +pub const SIOCSIFNETMASK: u32 = 35100; +pub const SIOCGIFMETRIC: u32 = 35101; +pub const SIOCSIFMETRIC: u32 = 35102; +pub const SIOCGIFMEM: u32 = 35103; +pub const SIOCSIFMEM: u32 = 35104; +pub const SIOCGIFMTU: u32 = 35105; +pub const SIOCSIFMTU: u32 = 35106; +pub const SIOCSIFNAME: u32 = 35107; +pub const SIOCSIFHWADDR: u32 = 35108; +pub const SIOCGIFENCAP: u32 = 35109; +pub const SIOCSIFENCAP: u32 = 35110; +pub const SIOCGIFHWADDR: u32 = 35111; +pub const SIOCGIFSLAVE: u32 = 35113; +pub const SIOCSIFSLAVE: u32 = 35120; +pub const SIOCADDMULTI: u32 = 35121; +pub const SIOCDELMULTI: u32 = 35122; +pub const SIOCGIFINDEX: u32 = 35123; +pub const SIOGIFINDEX: u32 = 35123; +pub const SIOCSIFPFLAGS: u32 = 35124; +pub const SIOCGIFPFLAGS: u32 = 35125; +pub const SIOCDIFADDR: u32 = 35126; +pub const SIOCSIFHWBROADCAST: u32 = 35127; +pub const SIOCGIFCOUNT: u32 = 35128; +pub const SIOCGIFBR: u32 = 35136; +pub const SIOCSIFBR: u32 = 35137; +pub const SIOCGIFTXQLEN: u32 = 35138; +pub const SIOCSIFTXQLEN: u32 = 35139; +pub const SIOCETHTOOL: u32 = 35142; +pub const SIOCGMIIPHY: u32 = 35143; +pub const SIOCGMIIREG: u32 = 35144; +pub const SIOCSMIIREG: u32 = 35145; +pub const SIOCWANDEV: u32 = 35146; +pub const SIOCOUTQNSD: u32 = 35147; +pub const SIOCGSKNS: u32 = 35148; +pub const SIOCDARP: u32 = 35155; +pub const SIOCGARP: u32 = 35156; +pub const SIOCSARP: u32 = 35157; +pub const SIOCDRARP: u32 = 35168; +pub const SIOCGRARP: u32 = 35169; +pub const SIOCSRARP: u32 = 35170; +pub const SIOCGIFMAP: u32 = 35184; +pub const SIOCSIFMAP: u32 = 35185; +pub const SIOCADDDLCI: u32 = 35200; +pub const SIOCDELDLCI: u32 = 35201; +pub const SIOCGIFVLAN: u32 = 35202; +pub const SIOCSIFVLAN: u32 = 35203; +pub const SIOCBONDENSLAVE: u32 = 35216; +pub const SIOCBONDRELEASE: u32 = 35217; +pub const SIOCBONDSETHWADDR: u32 = 35218; +pub const SIOCBONDSLAVEINFOQUERY: u32 = 35219; +pub const SIOCBONDINFOQUERY: u32 = 35220; +pub const SIOCBONDCHANGEACTIVE: u32 = 35221; +pub const SIOCBRADDBR: u32 = 35232; +pub const SIOCBRDELBR: u32 = 35233; +pub const SIOCBRADDIF: u32 = 35234; +pub const SIOCBRDELIF: u32 = 35235; +pub const SIOCSHWTSTAMP: u32 = 35248; +pub const SIOCGHWTSTAMP: u32 = 35249; +pub const SIOCDEVPRIVATE: u32 = 35312; +pub const SIOCPROTOPRIVATE: u32 = 35296; diff --git a/src/vmm/src/core/network/open_tap.rs b/src/vmm/src/core/network/open_tap.rs new file mode 100644 index 0000000..56ff32b --- /dev/null +++ b/src/vmm/src/core/network/open_tap.rs @@ -0,0 +1,77 @@ +// Copyright (c) 2020 Intel Corporation. All rights reserved. +// +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause + +use super::{tap, vnet_hdr_len}; +use crate::core::network::mac::MacAddr; +use crate::core::network::tap::Tap; +use std::io; +use std::net::Ipv4Addr; +use std::path::Path; +use tracing::warn; + +#[derive(Debug)] +pub enum Error { + ConvertHexStringToInt(std::num::ParseIntError), + MultiQueueNoTapSupport, + MultiQueueNoDeviceSupport, + ReadSysfsTunFlags(io::Error), + TapOpen(tap::Error), + TapSetIp(tap::Error), + TapSetNetmask(tap::Error), + TapSetMac(tap::Error), + TapGetMac(tap::Error), + TapSetVnetHdrSize(tap::Error), + TapSetMtu(tap::Error), + TapEnable(tap::Error), +} + +/// Create a new virtio network device with the given IP address and +/// netmask. +pub fn open_tap( + if_name: Option<&str>, + ip_addr: Option, + netmask: Option, + host_mac: &mut Option, + mtu: Option, + flags: Option, +) -> Result { + let vnet_hdr_size = vnet_hdr_len() as i32; + // Check if the given interface exists before we create it. + let tap_existed = if_name.map_or(false, |n| { + Path::new(&format!("/sys/class/net/{n}")).exists() + }); + + let tap: Tap = match if_name { + Some(name) => Tap::open_named(name, 1, flags).map_err(Error::TapOpen)?, + None => Tap::new(1).map_err(Error::TapOpen)?, + }; + // Don't overwrite ip configuration of existing interfaces: + if !tap_existed { + if let Some(ip) = ip_addr { + tap.set_ip_addr(ip).map_err(Error::TapSetIp)?; + } + if let Some(mask) = netmask { + tap.set_netmask(mask).map_err(Error::TapSetNetmask)?; + } + } else { + warn!( + "Tap {} already exists. IP configuration will not be overwritten.", + if_name.unwrap_or_default() + ); + } + if let Some(mac) = host_mac { + tap.set_mac_addr(*mac).map_err(Error::TapSetMac)? + } else { + *host_mac = Some(tap.get_mac_addr().map_err(Error::TapGetMac)?) + } + if let Some(mtu) = mtu { + tap.set_mtu(mtu as i32).map_err(Error::TapSetMtu)?; + } + tap.enable().map_err(Error::TapEnable)?; + + tap.set_vnet_hdr_size(vnet_hdr_size) + .map_err(Error::TapSetVnetHdrSize)?; + + Ok(tap) +} diff --git a/src/vmm/src/core/network/tap.rs b/src/vmm/src/core/network/tap.rs new file mode 100644 index 0000000..9988d53 --- /dev/null +++ b/src/vmm/src/core/network/tap.rs @@ -0,0 +1,318 @@ +// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// +// Portions Copyright 2017 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the THIRD-PARTY file. + +use super::{create_inet_socket, create_sockaddr, create_unix_socket, Error as NetUtilError}; +use crate::core::network::mac::MacAddr; +use crate::core::network::mac::MAC_ADDR_LEN; +use crate::core::network::net_gen; +use std::fs::File; +use std::io::{Error as IoError, Read, Result as IoResult, Write}; +use std::net; +use std::os::raw::*; +use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; +use vmm_sys_util::ioctl::{ioctl_with_mut_ref, ioctl_with_ref}; + +#[derive(Debug)] +pub enum Error { + OpenTun(IoError), + ConfigureTap(IoError), + GetFeatures(IoError), + MultiQueueKernelSupport, + Ioctl(c_ulong, IoError), + NetUtil(NetUtilError), + InvalidIfname, + MacParsing(IoError), +} + +pub type Result = ::std::result::Result; + +/// Handle for a network tap interface. +/// +/// For now, this simply wraps the file descriptor for the tap device so methods +/// can run ioctls on the interface. The tap interface fd will be closed when +/// Tap goes out of scope, and the kernel will clean up the interface +/// automatically. +#[derive(Debug)] +pub struct Tap { + tap_file: File, + if_name: Vec, +} + +impl PartialEq for Tap { + fn eq(&self, other: &Tap) -> bool { + self.if_name == other.if_name + } +} + +impl std::clone::Clone for Tap { + fn clone(&self) -> Self { + Tap { + tap_file: self.tap_file.try_clone().unwrap(), + if_name: self.if_name.clone(), + } + } +} + +// Returns a byte vector representing the contents of a null terminated C string which +// contains if_name. +fn build_terminated_if_name(if_name: &str) -> Result> { + // Convert the string slice to bytes, and shadow the variable, + // since we no longer need the &str version. + let if_name = if_name.as_bytes(); + + // TODO: the 16usize limit of the if_name member from struct Tap is pretty arbitrary. + // We leave it as is for now, but this should be refactored at some point. + if if_name.len() > 15 { + return Err(Error::InvalidIfname); + } + + let mut terminated_if_name = vec![b'\0'; if_name.len() + 1]; + terminated_if_name[..if_name.len()].copy_from_slice(if_name); + + Ok(terminated_if_name) +} + +impl Tap { + unsafe fn ioctl_with_ref(fd: &F, req: c_ulong, arg: &T) -> Result<()> { + let ret = ioctl_with_ref(fd, req, arg); + if ret < 0 { + return Err(Error::Ioctl(req, IoError::last_os_error())); + } + + Ok(()) + } + + pub fn open_named(if_name: &str, num_queue_pairs: usize, flags: Option) -> Result { + let terminated_if_name = build_terminated_if_name(if_name)?; + + // SAFETY: FFI call + let fd = unsafe { + // Open calls are safe because we give a constant null-terminated + // string and verify the result. + libc::open( + b"/dev/net/tun\0".as_ptr() as *const c_char, + flags.unwrap_or(libc::O_RDWR | libc::O_NONBLOCK | libc::O_CLOEXEC), + ) + }; + if fd < 0 { + return Err(Error::OpenTun(IoError::last_os_error())); + } + + // SAFETY: We just checked that the fd is valid. + let tuntap = unsafe { File::from_raw_fd(fd) }; + + // Let's validate some features before going any further. + // ioctl is safe since we call it with a valid tap fd and check the return + // value. + let mut features = 0; + // SAFETY: IOCTL with correct arguments + let ret = unsafe { ioctl_with_mut_ref(&tuntap, net_gen::TUNGETFEATURES(), &mut features) }; + if ret < 0 { + return Err(Error::GetFeatures(IoError::last_os_error())); + } + + // Check if the user parameters match the kernel support for MQ + if (features & net_gen::IFF_MULTI_QUEUE == 0) && num_queue_pairs > 1 { + return Err(Error::MultiQueueKernelSupport); + } + + // This is pretty messy because of the unions used by ifreq. Since we + // don't call as_mut on the same union field more than once, this block + // is safe. + let mut ifreq: net_gen::ifreq = Default::default(); + // SAFETY: see the comment above. + unsafe { + let ifrn_name = ifreq.ifr_ifrn.ifrn_name.as_mut(); + let name_slice = &mut ifrn_name[..terminated_if_name.len()]; + name_slice.copy_from_slice(terminated_if_name.as_slice()); + ifreq.ifr_ifru.ifru_flags = + (net_gen::IFF_TAP | net_gen::IFF_NO_PI | net_gen::IFF_VNET_HDR) as c_short; + if num_queue_pairs > 1 { + ifreq.ifr_ifru.ifru_flags |= net_gen::IFF_MULTI_QUEUE as c_short; + } + } + + // SAFETY: ioctl is safe since we call it with a valid tap fd and check the return + // value. + let ret = unsafe { ioctl_with_mut_ref(&tuntap, net_gen::TUNSETIFF(), &mut ifreq) }; + if ret < 0 { + return Err(Error::ConfigureTap(IoError::last_os_error())); + } + + // SAFETY: only the name is accessed, and it's cloned out. + let mut if_name = unsafe { ifreq.ifr_ifrn.ifrn_name }.to_vec(); + if_name.truncate(terminated_if_name.len() - 1); + Ok(Tap { + tap_file: tuntap, + if_name, + }) + } + + /// Create a new tap interface. + pub fn new(num_queue_pairs: usize) -> Result { + Self::open_named("taplet%d", num_queue_pairs, None) + } + + /// Set the host-side IP address for the tap interface. + pub fn set_ip_addr(&self, ip_addr: net::Ipv4Addr) -> Result<()> { + let sock = create_inet_socket().map_err(Error::NetUtil)?; + let addr = create_sockaddr(ip_addr); + + let mut ifreq = self.get_ifreq(); + + ifreq.ifr_ifru.ifru_addr = addr; + + // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. + unsafe { Self::ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFADDR as c_ulong, &ifreq) } + } + + /// Set mac addr for tap interface. + pub fn set_mac_addr(&self, addr: MacAddr) -> Result<()> { + // Checking if the mac address already matches the desired one + // is useful to avoid making the "set ioctl" in the case where + // the VMM is running without the privilege to do that. + // In practice this comes from a reboot after the configuration + // has been update with the kernel generated address. + if self.get_mac_addr()? == addr { + return Ok(()); + } + + let sock = create_unix_socket().map_err(Error::NetUtil)?; + + let mut ifreq = self.get_ifreq(); + + // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. + unsafe { Self::ioctl_with_ref(&sock, net_gen::sockios::SIOCGIFHWADDR as c_ulong, &ifreq)? }; + + // SAFETY: We only access one field of the ifru union + unsafe { + let ifru_hwaddr = &mut ifreq.ifr_ifru.ifru_hwaddr; + for (i, v) in addr.get_bytes().iter().enumerate() { + ifru_hwaddr.sa_data[i] = *v as c_uchar; + } + } + + // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. + unsafe { Self::ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFHWADDR as c_ulong, &ifreq) } + } + + /// Get mac addr for tap interface. + pub fn get_mac_addr(&self) -> Result { + let sock = create_unix_socket().map_err(Error::NetUtil)?; + + let ifreq = self.get_ifreq(); + + // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. + unsafe { Self::ioctl_with_ref(&sock, net_gen::sockios::SIOCGIFHWADDR as c_ulong, &ifreq)? }; + + // SAFETY: We only access one field of the ifru union + let addr = unsafe { + MacAddr::from_bytes(&ifreq.ifr_ifru.ifru_hwaddr.sa_data[0..MAC_ADDR_LEN]) + .map_err(Error::MacParsing)? + }; + Ok(addr) + } + + /// Set the netmask for the subnet that the tap interface will exist on. + pub fn set_netmask(&self, netmask: net::Ipv4Addr) -> Result<()> { + let sock = create_inet_socket().map_err(Error::NetUtil)?; + let addr = create_sockaddr(netmask); + + let mut ifreq = self.get_ifreq(); + + ifreq.ifr_ifru.ifru_addr = addr; + + // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. + unsafe { Self::ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFNETMASK as c_ulong, &ifreq) } + } + + pub fn set_mtu(&self, mtu: i32) -> Result<()> { + let sock = create_unix_socket().map_err(Error::NetUtil)?; + + let mut ifreq = self.get_ifreq(); + ifreq.ifr_ifru.ifru_mtu = mtu; + + // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. + unsafe { Self::ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFMTU as c_ulong, &ifreq) } + } + + // TODO: Use that when the virtio-net will be implemented, on device activation + // https://github.com/rust-vmm/vmm-reference/blob/89e4c8ba56b553eeefe53ab318a67b870a8b8e41/src/devices/src/virtio/net/device.rs#L104 + // + // /// Set the offload flags for the tap interface. + // pub fn set_offload(&self, flags: c_uint) -> Result<()> { + // // SAFETY: ioctl is safe. Called with a valid tap fd, and we check the return. + // unsafe { Self::ioctl_with_val(&self.tap_file, net_gen::TUNSETOFFLOAD(), flags as c_ulong) } + // } + + /// Enable the tap interface. + pub fn enable(&self) -> Result<()> { + let sock = create_unix_socket().map_err(Error::NetUtil)?; + + let mut ifreq = self.get_ifreq(); + + // SAFETY: IOCTL with correct arguments + unsafe { Self::ioctl_with_ref(&sock, net_gen::sockios::SIOCGIFFLAGS as c_ulong, &ifreq)? }; + + // If TAP device is already up don't try and enable it + // SAFETY: access a union field + let ifru_flags = unsafe { ifreq.ifr_ifru.ifru_flags }; + if ifru_flags & net_gen::net_device_flags_IFF_UP as i16 + == net_gen::net_device_flags_IFF_UP as i16 + { + return Ok(()); + } + + ifreq.ifr_ifru.ifru_flags = net_gen::net_device_flags_IFF_UP as i16; + + // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. + unsafe { Self::ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFFLAGS as c_ulong, &ifreq) } + } + + /// Set the size of the vnet hdr. + pub fn set_vnet_hdr_size(&self, size: c_int) -> Result<()> { + // SAFETY: ioctl is safe. Called with a valid tap fd, and we check the return. + unsafe { Self::ioctl_with_ref(&self.tap_file, net_gen::TUNSETVNETHDRSZ(), &size) } + } + + fn get_ifreq(&self) -> net_gen::ifreq { + let mut ifreq: net_gen::ifreq = Default::default(); + + // This sets the name of the interface, which is the only entry + // in a single-field union. + // SAFETY: access union fields and we're sure the copy is okay. + unsafe { + let ifrn_name = ifreq.ifr_ifrn.ifrn_name.as_mut(); + let name_slice = &mut ifrn_name[..self.if_name.len()]; + name_slice.copy_from_slice(&self.if_name); + } + + ifreq + } +} + +impl Read for Tap { + fn read(&mut self, buf: &mut [u8]) -> IoResult { + self.tap_file.read(buf) + } +} + +impl Write for Tap { + fn write(&mut self, buf: &[u8]) -> IoResult { + self.tap_file.write(buf) + } + + fn flush(&mut self) -> IoResult<()> { + Ok(()) + } +} + +impl AsRawFd for Tap { + fn as_raw_fd(&self) -> RawFd { + self.tap_file.as_raw_fd() + } +} diff --git a/src/vmm/src/core/vmm.rs b/src/vmm/src/core/vmm.rs index 5357b79..5b8e21e 100644 --- a/src/vmm/src/core/vmm.rs +++ b/src/vmm/src/core/vmm.rs @@ -9,6 +9,7 @@ use kvm_bindings::{kvm_userspace_memory_region, KVM_MAX_CPUID_ENTRIES}; use kvm_ioctls::{Kvm, VmFd}; use linux_loader::loader::KernelLoaderResult; use std::io; +use std::net::Ipv4Addr; use std::os::unix::io::AsRawFd; use std::os::unix::prelude::RawFd; use std::path::Path; @@ -18,11 +19,15 @@ use tracing::info; use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryMmap, GuestMemoryRegion}; use vmm_sys_util::terminal::Terminal; +use super::network::open_tap::open_tap; +use super::network::tap::Tap; + pub struct VMM { vm_fd: VmFd, kvm: Kvm, guest_memory: GuestMemoryMmap, vcpus: Vec, + _tap: Tap, serial: Arc>, epoll: EpollContext, @@ -30,7 +35,7 @@ pub struct VMM { impl VMM { /// Create a new VMM. - pub fn new() -> Result { + pub fn new(tap_ip_addr: Ipv4Addr, tap_netmask: Ipv4Addr) -> Result { // Open /dev/kvm and get a file descriptor to it. let kvm = Kvm::new().map_err(Error::KvmIoctl)?; @@ -41,11 +46,22 @@ impl VMM { let epoll = EpollContext::new().map_err(Error::EpollError)?; epoll.add_stdin().map_err(Error::EpollError)?; + let tap = open_tap( + None, + Some(tap_ip_addr), + Some(tap_netmask), + &mut None, + None, + None, + ) + .map_err(Error::OpenTap)?; + let vmm = VMM { vm_fd, kvm, guest_memory: GuestMemoryMmap::default(), vcpus: vec![], + _tap: tap, serial: Arc::new(Mutex::new( LumperSerial::new().map_err(Error::SerialCreation)?, )), diff --git a/src/vmm/src/main.rs b/src/vmm/src/main.rs index cbc180b..7599367 100644 --- a/src/vmm/src/main.rs +++ b/src/vmm/src/main.rs @@ -27,7 +27,8 @@ fn main() -> Result<(), Error> { ); // Create a new VMM - let mut vmm = VMM::new().map_err(Error::VmmNew)?; + let mut vmm = + VMM::new(args.network_host_ip, args.network_host_netmask).map_err(Error::VmmNew)?; vmm.configure(args.cpus, args.memory, &args.kernel) .map_err(Error::VmmConfigure)?;