bpf: initial bpf bindings

pull/1/head
Alessandro Decina 4 years ago
parent 8327ffbb8d
commit cdf960aaa1

@ -1,2 +1,2 @@
[workspace]
members = ["aya"]
members = ["aya", "xtask"]

@ -0,0 +1,2 @@
[workspace]
members = ["aya-bpf", "aya-bpf-macros"]

@ -0,0 +1,32 @@
language: rust
matrix:
include:
# MSRV
- env: TARGET=x86_64-unknown-linux-gnu
rust: 1.30.0
- env: TARGET=x86_64-unknown-linux-gnu
rust: stable
before_install: set -e
install:
- sh ci/install.sh
script:
- sh ci/script.sh
after_script: set +e
cache: cargo
branches:
only:
- master
- staging
- trying
notifications:
email:
on_success: never

@ -0,0 +1,66 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to $[Semantic Versioning](http://semver.org/).
## [Unreleased]
## [v0.2.1] - 2019-11-16
### Added
- Support for the `xtensa`, `riscv32` and `riscv64` architectures
## [v0.2.0] - 2019-02-06
### Changed
- [breaking-change] `cty::c_void` is now a type alias of `core::ffi::c_void`.
## [v0.1.5] - 2017-05-29
### Added
- More types like `int32_t`
## [v0.1.4] - 2017-05-29
### Added
- Support for the `msp430` architecture.
### Fixed
- [breaking-change] The type definitions of `c_long` and `c_ulong`.
## [v0.1.3] - 2017-05-29 - YANKED
### Added
- Support for the `nvptx` and `nvptx64` architectures.
## [v0.1.2] - 2017-05-29 - YANKED
### Fixed
- [breaking-change] The type definitions of `c_int` and `c_uint`.
## [v0.1.1] - 2017-05-29 - YANKED
### Fixed
- [breaking-change] The type definitions of `c_long`, `c_ulong` and
`c_longlong`.
## v0.1.0 - 2017-05-24 - YANKED
- Initial release
[Unreleased]: https://github.com/japaric/cty/compare/v0.2.1...HEAD
[v0.2.1]: https://github.com/japaric/cty/compare/v0.2.0...v0.2.1
[v0.2.0]: https://github.com/japaric/cty/compare/v0.1.5...v0.2.0
[v0.1.5]: https://github.com/japaric/cty/compare/v0.1.4...v0.1.5
[v0.1.4]: https://github.com/japaric/cty/compare/v0.1.3...v0.1.4
[v0.1.3]: https://github.com/japaric/cty/compare/v0.1.2...v0.1.3
[v0.1.2]: https://github.com/japaric/cty/compare/v0.1.1...v0.1.2
[v0.1.1]: https://github.com/japaric/cty/compare/v0.1.0...v0.1.1

@ -0,0 +1,8 @@
[package]
authors = ["Jorge Aparicio <jorge@japaric.io>"]
categories = ["embedded", "external-ffi-bindings" ,"no-std"]
description = "Type aliases to C types like c_int for use with bindgen"
documentation = "https://docs.rs/cty"
license = "MIT OR Apache-2.0"
name = "aya-bpf-cty"
version = "0.2.1"

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -0,0 +1,25 @@
Copyright (c) 2017 Jorge Aparicio
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

@ -0,0 +1,22 @@
[![crates.io](https://img.shields.io/crates/v/cty.svg)](https://crates.io/crates/cty)
[![crates.io](https://img.shields.io/crates/d/cty.svg)](https://crates.io/crates/cty)
# `cty`
> Type aliases to C types like c_int for use with bindgen
## License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

@ -0,0 +1,9 @@
use std::env;
fn main() {
if !env::var("CARGO_CFG_BPF_TARGET_ARCH").is_ok() {
let arch = env::var("HOST").unwrap();
let arch = arch.splitn(2, "-").next().unwrap();
println!("cargo:rustc-cfg=bpf_target_arch=\"{}\"", arch);
}
}

@ -0,0 +1,7 @@
set -ex
main() {
return
}
main

@ -0,0 +1,10 @@
set -ex
main() {
for target in $(rustup target list | grep linux-gnu | cut -d' ' -f1); do
rustup target add $target || continue
cargo check --target $target
done
}
main

@ -0,0 +1,139 @@
//! Type aliases to C types like c_int for use with bindgen
//!
//! # MSRV
//!
//! This crate is guaranteed to compile on stable Rust 1.30.0 and up. It *might* compile with older
//! versions but that may change in any new patch release.
#![no_std]
#![allow(non_camel_case_types)]
#![deny(warnings)]
// AD = Architecture dependent
pub use ad::*;
// OD = OS dependent
pub use od::*;
// PWD = Pointer Width Dependent
pub use pwd::*;
#[cfg(any(target_arch = "bpfel", target_arch = "bpfeb"))]
mod ad {
pub type c_int = i32;
pub type c_uint = u32;
#[cfg(bpf_target_arch = "aarch64")]
pub type c_char = super::c_uchar;
#[cfg(any(bpf_target_arch = "x86", bpf_target_arch = "x86_64"))]
pub type c_char = super::c_schar;
#[cfg(all(not(bpf_target_arch), host_arch = "aarch64"))]
pub type c_char = super::c_uchar;
}
#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "asmjs",
target_arch = "wasm32",
target_arch = "wasm64",
target_arch = "powerpc",
target_arch = "powerpc64",
target_arch = "s390x",
target_arch = "riscv32",
target_arch = "riscv64"
))]
mod ad {
pub type c_char = ::c_uchar;
pub type c_int = i32;
pub type c_uint = u32;
}
#[cfg(any(
target_arch = "mips",
target_arch = "mips64",
target_arch = "sparc64",
target_arch = "x86",
target_arch = "x86_64",
target_arch = "nvptx",
target_arch = "nvptx64",
target_arch = "xtensa"
))]
mod ad {
pub type c_char = ::c_schar;
pub type c_int = i32;
pub type c_uint = u32;
}
#[cfg(target_arch = "msp430")]
mod ad {
pub type c_char = ::c_uchar;
pub type c_int = i16;
pub type c_uint = u16;
}
// NOTE c_{,u}long definitions come from libc v0.2.3
#[cfg(not(any(windows, target_os = "redox", target_os = "solaris")))]
mod od {
#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
pub type c_long = i32;
#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
pub type c_ulong = u32;
#[cfg(target_pointer_width = "64")]
pub type c_long = i64;
#[cfg(target_pointer_width = "64")]
pub type c_ulong = u64;
}
#[cfg(windows)]
mod od {
pub type c_long = i32;
pub type c_ulong = u32;
}
#[cfg(any(target_os = "redox", target_os = "solaris"))]
mod od {
pub type c_long = i64;
pub type c_ulong = u64;
}
#[cfg(target_pointer_width = "32")]
mod pwd {}
#[cfg(target_pointer_width = "64")]
mod pwd {}
pub type int8_t = i8;
pub type int16_t = i16;
pub type int32_t = i32;
pub type int64_t = i64;
pub type uint8_t = u8;
pub type uint16_t = u16;
pub type uint32_t = u32;
pub type uint64_t = u64;
pub type c_schar = i8;
pub type c_short = i16;
pub type c_longlong = i64;
pub type c_uchar = u8;
pub type c_ushort = u16;
pub type c_ulonglong = u64;
pub type c_float = f32;
pub type c_double = f64;
pub type intmax_t = i64;
pub type uintmax_t = u64;
pub type size_t = usize;
pub type ptrdiff_t = isize;
pub type intptr_t = isize;
pub type uintptr_t = usize;
pub type ssize_t = isize;
pub type c_void = core::ffi::c_void;

@ -0,0 +1,13 @@
[package]
name = "aya-bpf-macros"
version = "0.1.0"
authors = ["Alessandro Decina <alessandro.d@gmail.com>"]
edition = "2018"
[lib]
proc-macro = true
[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
syn = {version = "1.0", features = ["full"]}

@ -0,0 +1,122 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{
parse::{Parse, ParseStream},
punctuated::{Pair, Punctuated},
token::Eq,
Error, Ident, ItemFn, ItemStatic, LitStr, Result, Token,
};
pub struct NameValue {
name: Ident,
_eq: Eq,
value: LitStr,
}
pub struct Args {
args: Vec<NameValue>,
}
impl Parse for Args {
fn parse(input: ParseStream) -> Result<Args> {
let args = Punctuated::<NameValue, Token![,]>::parse_terminated_with(input, |input| {
Ok(NameValue {
name: input.parse()?,
_eq: input.parse()?,
value: input.parse()?,
})
})?
.into_pairs()
.map(|pair| match pair {
Pair::Punctuated(name_val, _) => name_val,
Pair::End(name_val) => name_val,
})
.collect();
Ok(Args { args })
}
}
pub struct Map {
item: ItemStatic,
name: String,
}
impl Map {
pub fn from_syn(args: Args, item: ItemStatic) -> Result<Map> {
let name = name_arg(&args)?.unwrap_or_else(|| item.ident.to_string());
Ok(Map { item, name })
}
pub fn expand(&self) -> Result<TokenStream> {
let section_name = format!("maps/{}", self.name);
let item = &self.item;
Ok(quote! {
#[no_mangle]
#[link_section = #section_name]
#item
})
}
}
pub struct Probe {
kind: ProbeKind,
item: ItemFn,
name: String,
}
impl Probe {
pub fn from_syn(kind: ProbeKind, args: Args, item: ItemFn) -> Result<Probe> {
let name = name_arg(&args)?.unwrap_or_else(|| item.sig.ident.to_string());
Ok(Probe { kind, item, name })
}
pub fn expand(&self) -> Result<TokenStream> {
let section_name = format!("{}/{}", self.kind, self.name);
let fn_name = &self.item.sig.ident;
let item = &self.item;
Ok(quote! {
#[no_mangle]
#[link_section = #section_name]
fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
let _ = #fn_name(::aya_bpf::programs::ProbeContext::new(ctx));
return 0;
#item
}
})
}
}
fn name_arg(args: &Args) -> Result<Option<String>> {
for arg in &args.args {
if arg.name == "name" {
return Ok(Some(arg.value.value()));
} else {
return Err(Error::new_spanned(&arg.name, "invalid argument"));
}
}
Ok(None)
}
#[derive(Debug, Copy, Clone)]
pub enum ProbeKind {
KProbe,
KRetProbe,
UProbe,
URetProbe,
}
impl std::fmt::Display for ProbeKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use ProbeKind::*;
match self {
KProbe => write!(f, "kprobe"),
KRetProbe => write!(f, "kretprobe"),
UProbe => write!(f, "uprobe"),
URetProbe => write!(f, "uretprobe"),
}
}
}

@ -0,0 +1,46 @@
mod expand;
use expand::{Args, Map, Probe, ProbeKind};
use proc_macro::TokenStream;
use syn::{parse_macro_input, ItemFn, ItemStatic};
#[proc_macro_attribute]
pub fn map(attrs: TokenStream, item: TokenStream) -> TokenStream {
let args = parse_macro_input!(attrs as Args);
let item = parse_macro_input!(item as ItemStatic);
Map::from_syn(args, item)
.and_then(|u| u.expand())
.unwrap_or_else(|err| err.to_compile_error())
.into()
}
#[proc_macro_attribute]
pub fn kprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
probe(ProbeKind::KProbe, attrs, item)
}
#[proc_macro_attribute]
pub fn kretprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
probe(ProbeKind::KRetProbe, attrs, item)
}
#[proc_macro_attribute]
pub fn uprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
probe(ProbeKind::UProbe, attrs, item)
}
#[proc_macro_attribute]
pub fn uretprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
probe(ProbeKind::URetProbe, attrs, item)
}
fn probe(kind: ProbeKind, attrs: TokenStream, item: TokenStream) -> TokenStream {
let args = parse_macro_input!(attrs as Args);
let item = parse_macro_input!(item as ItemFn);
Probe::from_syn(kind, args, item)
.and_then(|u| u.expand())
.unwrap_or_else(|err| err.to_compile_error())
.into()
}

@ -0,0 +1,9 @@
[package]
name = "aya-bpf"
version = "0.1.0"
authors = ["Alessandro Decina <alessandro.d@gmail.com>"]
edition = "2018"
[dependencies]
aya-bpf-cty = { path = "../aya-bpf-cty" }
aya-bpf-macros = { path = "../aya-bpf-macros" }

@ -0,0 +1,3 @@
#include <linux/types.h>
#include <linux/bpf.h>
#include "bpf_helpers.h"

@ -0,0 +1,932 @@
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage> {
storage: Storage,
}
impl<Storage> __BindgenBitfieldUnit<Storage> {
#[inline]
pub const fn new(storage: Storage) -> Self {
Self { storage }
}
}
impl<Storage> __BindgenBitfieldUnit<Storage>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
let byte_index = index / 8;
let byte = self.storage.as_ref()[byte_index];
let bit_index = if cfg!(target_endian = "big") {
7 - (index % 8)
} else {
index % 8
};
let mask = 1 << bit_index;
byte & mask == mask
}
#[inline]
pub fn set_bit(&mut self, index: usize, val: bool) {
debug_assert!(index / 8 < self.storage.as_ref().len());
let byte_index = index / 8;
let byte = &mut self.storage.as_mut()[byte_index];
let bit_index = if cfg!(target_endian = "big") {
7 - (index % 8)
} else {
index % 8
};
let mask = 1 << bit_index;
if val {
*byte |= mask;
} else {
*byte &= !mask;
}
}
#[inline]
pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {
debug_assert!(bit_width <= 64);
debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
let mut val = 0;
for i in 0..(bit_width as usize) {
if self.get_bit(i + bit_offset) {
let index = if cfg!(target_endian = "big") {
bit_width as usize - 1 - i
} else {
i
};
val |= 1 << index;
}
}
val
}
#[inline]
pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
debug_assert!(bit_width <= 64);
debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
for i in 0..(bit_width as usize) {
let mask = 1 << i;
let val_bit_is_set = val & mask == mask;
let index = if cfg!(target_endian = "big") {
bit_width as usize - 1 - i
} else {
i
};
self.set_bit(index + bit_offset, val_bit_is_set);
}
}
}
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_JMP32: u32 = 6;
pub const BPF_ALU64: u32 = 7;
pub const BPF_DW: u32 = 24;
pub const BPF_XADD: u32 = 192;
pub const BPF_MOV: u32 = 176;
pub const BPF_ARSH: u32 = 192;
pub const BPF_END: u32 = 208;
pub const BPF_TO_LE: u32 = 0;
pub const BPF_TO_BE: u32 = 8;
pub const BPF_FROM_LE: u32 = 0;
pub const BPF_FROM_BE: u32 = 8;
pub const BPF_JNE: u32 = 80;
pub const BPF_JLT: u32 = 160;
pub const BPF_JLE: u32 = 176;
pub const BPF_JSGT: u32 = 96;
pub const BPF_JSGE: u32 = 112;
pub const BPF_JSLT: u32 = 192;
pub const BPF_JSLE: u32 = 208;
pub const BPF_CALL: u32 = 128;
pub const BPF_EXIT: u32 = 144;
pub const BPF_F_ALLOW_OVERRIDE: u32 = 1;
pub const BPF_F_ALLOW_MULTI: u32 = 2;
pub const BPF_F_REPLACE: u32 = 4;
pub const BPF_F_STRICT_ALIGNMENT: u32 = 1;
pub const BPF_F_ANY_ALIGNMENT: u32 = 2;
pub const BPF_F_TEST_RND_HI32: u32 = 4;
pub const BPF_F_TEST_STATE_FREQ: u32 = 8;
pub const BPF_PSEUDO_MAP_FD: u32 = 1;
pub const BPF_PSEUDO_MAP_VALUE: u32 = 2;
pub const BPF_PSEUDO_CALL: u32 = 1;
pub const BPF_F_QUERY_EFFECTIVE: u32 = 1;
pub const BPF_BUILD_ID_SIZE: u32 = 20;
pub const BPF_OBJ_NAME_LEN: u32 = 16;
pub const BPF_TAG_SIZE: u32 = 8;
pub type __u8 = ::aya_bpf_cty::c_uchar;
pub type __u16 = ::aya_bpf_cty::c_ushort;
pub type __s32 = ::aya_bpf_cty::c_int;
pub type __u32 = ::aya_bpf_cty::c_uint;
pub type __s64 = ::aya_bpf_cty::c_longlong;
pub type __u64 = ::aya_bpf_cty::c_ulonglong;
pub type __be16 = __u16;
pub type __be32 = __u32;
pub type __wsum = __u32;
pub const BPF_REG_0: ::aya_bpf_cty::c_uint = 0;
pub const BPF_REG_1: ::aya_bpf_cty::c_uint = 1;
pub const BPF_REG_2: ::aya_bpf_cty::c_uint = 2;
pub const BPF_REG_3: ::aya_bpf_cty::c_uint = 3;
pub const BPF_REG_4: ::aya_bpf_cty::c_uint = 4;
pub const BPF_REG_5: ::aya_bpf_cty::c_uint = 5;
pub const BPF_REG_6: ::aya_bpf_cty::c_uint = 6;
pub const BPF_REG_7: ::aya_bpf_cty::c_uint = 7;
pub const BPF_REG_8: ::aya_bpf_cty::c_uint = 8;
pub const BPF_REG_9: ::aya_bpf_cty::c_uint = 9;
pub const BPF_REG_10: ::aya_bpf_cty::c_uint = 10;
pub const __MAX_BPF_REG: ::aya_bpf_cty::c_uint = 11;
pub type _bindgen_ty_1 = ::aya_bpf_cty::c_uint;
pub const BPF_MAP_TYPE_UNSPEC: bpf_map_type = 0;
pub const BPF_MAP_TYPE_HASH: bpf_map_type = 1;
pub const BPF_MAP_TYPE_ARRAY: bpf_map_type = 2;
pub const BPF_MAP_TYPE_PROG_ARRAY: bpf_map_type = 3;
pub const BPF_MAP_TYPE_PERF_EVENT_ARRAY: bpf_map_type = 4;
pub const BPF_MAP_TYPE_PERCPU_HASH: bpf_map_type = 5;
pub const BPF_MAP_TYPE_PERCPU_ARRAY: bpf_map_type = 6;
pub const BPF_MAP_TYPE_STACK_TRACE: bpf_map_type = 7;
pub const BPF_MAP_TYPE_CGROUP_ARRAY: bpf_map_type = 8;
pub const BPF_MAP_TYPE_LRU_HASH: bpf_map_type = 9;
pub const BPF_MAP_TYPE_LRU_PERCPU_HASH: bpf_map_type = 10;
pub const BPF_MAP_TYPE_LPM_TRIE: bpf_map_type = 11;
pub const BPF_MAP_TYPE_ARRAY_OF_MAPS: bpf_map_type = 12;
pub const BPF_MAP_TYPE_HASH_OF_MAPS: bpf_map_type = 13;
pub const BPF_MAP_TYPE_DEVMAP: bpf_map_type = 14;
pub const BPF_MAP_TYPE_SOCKMAP: bpf_map_type = 15;
pub const BPF_MAP_TYPE_CPUMAP: bpf_map_type = 16;
pub const BPF_MAP_TYPE_XSKMAP: bpf_map_type = 17;
pub const BPF_MAP_TYPE_SOCKHASH: bpf_map_type = 18;
pub const BPF_MAP_TYPE_CGROUP_STORAGE: bpf_map_type = 19;
pub const BPF_MAP_TYPE_REUSEPORT_SOCKARRAY: bpf_map_type = 20;
pub const BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE: bpf_map_type = 21;
pub const BPF_MAP_TYPE_QUEUE: bpf_map_type = 22;
pub const BPF_MAP_TYPE_STACK: bpf_map_type = 23;
pub const BPF_MAP_TYPE_SK_STORAGE: bpf_map_type = 24;
pub const BPF_MAP_TYPE_DEVMAP_HASH: bpf_map_type = 25;
pub const BPF_MAP_TYPE_STRUCT_OPS: bpf_map_type = 26;
pub const BPF_MAP_TYPE_RINGBUF: bpf_map_type = 27;
pub type bpf_map_type = ::aya_bpf_cty::c_uint;
pub const BPF_ANY: ::aya_bpf_cty::c_uint = 0;
pub const BPF_NOEXIST: ::aya_bpf_cty::c_uint = 1;
pub const BPF_EXIST: ::aya_bpf_cty::c_uint = 2;
pub const BPF_F_LOCK: ::aya_bpf_cty::c_uint = 4;
pub type _bindgen_ty_2 = ::aya_bpf_cty::c_uint;
pub const BPF_F_NO_PREALLOC: ::aya_bpf_cty::c_uint = 1;
pub const BPF_F_NO_COMMON_LRU: ::aya_bpf_cty::c_uint = 2;
pub const BPF_F_NUMA_NODE: ::aya_bpf_cty::c_uint = 4;
pub const BPF_F_RDONLY: ::aya_bpf_cty::c_uint = 8;
pub const BPF_F_WRONLY: ::aya_bpf_cty::c_uint = 16;
pub const BPF_F_STACK_BUILD_ID: ::aya_bpf_cty::c_uint = 32;
pub const BPF_F_ZERO_SEED: ::aya_bpf_cty::c_uint = 64;
pub const BPF_F_RDONLY_PROG: ::aya_bpf_cty::c_uint = 128;
pub const BPF_F_WRONLY_PROG: ::aya_bpf_cty::c_uint = 256;
pub const BPF_F_CLONE: ::aya_bpf_cty::c_uint = 512;
pub const BPF_F_MMAPABLE: ::aya_bpf_cty::c_uint = 1024;
pub type _bindgen_ty_3 = ::aya_bpf_cty::c_uint;
pub const BPF_F_RECOMPUTE_CSUM: ::aya_bpf_cty::c_uint = 1;
pub const BPF_F_INVALIDATE_HASH: ::aya_bpf_cty::c_uint = 2;
pub type _bindgen_ty_4 = ::aya_bpf_cty::c_uint;
pub const BPF_F_HDR_FIELD_MASK: ::aya_bpf_cty::c_uint = 15;
pub type _bindgen_ty_5 = ::aya_bpf_cty::c_uint;
pub const BPF_F_PSEUDO_HDR: ::aya_bpf_cty::c_uint = 16;
pub const BPF_F_MARK_MANGLED_0: ::aya_bpf_cty::c_uint = 32;
pub const BPF_F_MARK_ENFORCE: ::aya_bpf_cty::c_uint = 64;
pub type _bindgen_ty_6 = ::aya_bpf_cty::c_uint;
pub const BPF_F_INGRESS: ::aya_bpf_cty::c_uint = 1;
pub type _bindgen_ty_7 = ::aya_bpf_cty::c_uint;
pub const BPF_F_TUNINFO_IPV6: ::aya_bpf_cty::c_uint = 1;
pub type _bindgen_ty_8 = ::aya_bpf_cty::c_uint;
pub const BPF_F_SKIP_FIELD_MASK: ::aya_bpf_cty::c_uint = 255;
pub const BPF_F_USER_STACK: ::aya_bpf_cty::c_uint = 256;
pub const BPF_F_FAST_STACK_CMP: ::aya_bpf_cty::c_uint = 512;
pub const BPF_F_REUSE_STACKID: ::aya_bpf_cty::c_uint = 1024;
pub const BPF_F_USER_BUILD_ID: ::aya_bpf_cty::c_uint = 2048;
pub type _bindgen_ty_9 = ::aya_bpf_cty::c_uint;
pub const BPF_F_ZERO_CSUM_TX: ::aya_bpf_cty::c_uint = 2;
pub const BPF_F_DONT_FRAGMENT: ::aya_bpf_cty::c_uint = 4;
pub const BPF_F_SEQ_NUMBER: ::aya_bpf_cty::c_uint = 8;
pub type _bindgen_ty_10 = ::aya_bpf_cty::c_uint;
pub const BPF_F_INDEX_MASK: ::aya_bpf_cty::c_ulong = 4294967295;
pub const BPF_F_CURRENT_CPU: ::aya_bpf_cty::c_ulong = 4294967295;
pub const BPF_F_CTXLEN_MASK: ::aya_bpf_cty::c_ulong = 4503595332403200;
pub type _bindgen_ty_11 = ::aya_bpf_cty::c_ulong;
pub const BPF_F_CURRENT_NETNS: ::aya_bpf_cty::c_int = -1;
pub type _bindgen_ty_12 = ::aya_bpf_cty::c_int;
pub const BPF_CSUM_LEVEL_QUERY: ::aya_bpf_cty::c_uint = 0;
pub const BPF_CSUM_LEVEL_INC: ::aya_bpf_cty::c_uint = 1;
pub const BPF_CSUM_LEVEL_DEC: ::aya_bpf_cty::c_uint = 2;
pub const BPF_CSUM_LEVEL_RESET: ::aya_bpf_cty::c_uint = 3;
pub type _bindgen_ty_13 = ::aya_bpf_cty::c_uint;
pub const BPF_F_ADJ_ROOM_FIXED_GSO: ::aya_bpf_cty::c_uint = 1;
pub const BPF_F_ADJ_ROOM_ENCAP_L3_IPV4: ::aya_bpf_cty::c_uint = 2;
pub const BPF_F_ADJ_ROOM_ENCAP_L3_IPV6: ::aya_bpf_cty::c_uint = 4;
pub const BPF_F_ADJ_ROOM_ENCAP_L4_GRE: ::aya_bpf_cty::c_uint = 8;
pub const BPF_F_ADJ_ROOM_ENCAP_L4_UDP: ::aya_bpf_cty::c_uint = 16;
pub const BPF_F_ADJ_ROOM_NO_CSUM_RESET: ::aya_bpf_cty::c_uint = 32;
pub type _bindgen_ty_14 = ::aya_bpf_cty::c_uint;
pub const BPF_ADJ_ROOM_ENCAP_L2_MASK: ::aya_bpf_cty::c_uint = 255;
pub const BPF_ADJ_ROOM_ENCAP_L2_SHIFT: ::aya_bpf_cty::c_uint = 56;
pub type _bindgen_ty_15 = ::aya_bpf_cty::c_uint;
pub const BPF_F_SYSCTL_BASE_NAME: ::aya_bpf_cty::c_uint = 1;
pub type _bindgen_ty_16 = ::aya_bpf_cty::c_uint;
pub const BPF_SK_STORAGE_GET_F_CREATE: ::aya_bpf_cty::c_uint = 1;
pub type _bindgen_ty_17 = ::aya_bpf_cty::c_uint;
pub const BPF_F_GET_BRANCH_RECORDS_SIZE: ::aya_bpf_cty::c_uint = 1;
pub type _bindgen_ty_18 = ::aya_bpf_cty::c_uint;
pub const BPF_RB_NO_WAKEUP: ::aya_bpf_cty::c_uint = 1;
pub const BPF_RB_FORCE_WAKEUP: ::aya_bpf_cty::c_uint = 2;
pub type _bindgen_ty_19 = ::aya_bpf_cty::c_uint;
pub const BPF_RB_AVAIL_DATA: ::aya_bpf_cty::c_uint = 0;
pub const BPF_RB_RING_SIZE: ::aya_bpf_cty::c_uint = 1;
pub const BPF_RB_CONS_POS: ::aya_bpf_cty::c_uint = 2;
pub const BPF_RB_PROD_POS: ::aya_bpf_cty::c_uint = 3;
pub type _bindgen_ty_20 = ::aya_bpf_cty::c_uint;
pub const BPF_RINGBUF_BUSY_BIT: ::aya_bpf_cty::c_uint = 2147483648;
pub const BPF_RINGBUF_DISCARD_BIT: ::aya_bpf_cty::c_uint = 1073741824;
pub const BPF_RINGBUF_HDR_SZ: ::aya_bpf_cty::c_uint = 8;
pub type _bindgen_ty_21 = ::aya_bpf_cty::c_uint;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct __sk_buff {
pub len: __u32,
pub pkt_type: __u32,
pub mark: __u32,
pub queue_mapping: __u32,
pub protocol: __u32,
pub vlan_present: __u32,
pub vlan_tci: __u32,
pub vlan_proto: __u32,
pub priority: __u32,
pub ingress_ifindex: __u32,
pub ifindex: __u32,
pub tc_index: __u32,
pub cb: [__u32; 5usize],
pub hash: __u32,
pub tc_classid: __u32,
pub data: __u32,
pub data_end: __u32,
pub napi_id: __u32,
pub family: __u32,
pub remote_ip4: __u32,
pub local_ip4: __u32,
pub remote_ip6: [__u32; 4usize],
pub local_ip6: [__u32; 4usize],
pub remote_port: __u32,
pub local_port: __u32,
pub data_meta: __u32,
pub __bindgen_anon_1: __sk_buff__bindgen_ty_1,
pub tstamp: __u64,
pub wire_len: __u32,
pub gso_segs: __u32,
pub __bindgen_anon_2: __sk_buff__bindgen_ty_2,
pub gso_size: __u32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union __sk_buff__bindgen_ty_1 {
pub flow_keys: *mut bpf_flow_keys,
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>,
_bindgen_union_align: u64,
}
impl __sk_buff__bindgen_ty_1 {
#[inline]
pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 8usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default();
__bindgen_bitfield_unit
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union __sk_buff__bindgen_ty_2 {
pub sk: *mut bpf_sock,
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>,
_bindgen_union_align: u64,
}
impl __sk_buff__bindgen_ty_2 {
#[inline]
pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 8usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default();
__bindgen_bitfield_unit
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct bpf_tunnel_key {
pub tunnel_id: __u32,
pub __bindgen_anon_1: bpf_tunnel_key__bindgen_ty_1,
pub tunnel_tos: __u8,
pub tunnel_ttl: __u8,
pub tunnel_ext: __u16,
pub tunnel_label: __u32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union bpf_tunnel_key__bindgen_ty_1 {
pub remote_ipv4: __u32,
pub remote_ipv6: [__u32; 4usize],
_bindgen_union_align: [u32; 4usize],
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct bpf_xfrm_state {
pub reqid: __u32,
pub spi: __u32,
pub family: __u16,
pub ext: __u16,
pub __bindgen_anon_1: bpf_xfrm_state__bindgen_ty_1,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union bpf_xfrm_state__bindgen_ty_1 {
pub remote_ipv4: __u32,
pub remote_ipv6: [__u32; 4usize],
_bindgen_union_align: [u32; 4usize],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_sock {
pub bound_dev_if: __u32,
pub family: __u32,
pub type_: __u32,
pub protocol: __u32,
pub mark: __u32,
pub priority: __u32,
pub src_ip4: __u32,
pub src_ip6: [__u32; 4usize],
pub src_port: __u32,
pub dst_port: __u32,
pub dst_ip4: __u32,
pub dst_ip6: [__u32; 4usize],
pub state: __u32,
pub rx_queue_mapping: __s32,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_tcp_sock {
pub snd_cwnd: __u32,
pub srtt_us: __u32,
pub rtt_min: __u32,
pub snd_ssthresh: __u32,
pub rcv_nxt: __u32,
pub snd_nxt: __u32,
pub snd_una: __u32,
pub mss_cache: __u32,
pub ecn_flags: __u32,
pub rate_delivered: __u32,
pub rate_interval_us: __u32,
pub packets_out: __u32,
pub retrans_out: __u32,
pub total_retrans: __u32,
pub segs_in: __u32,
pub data_segs_in: __u32,
pub segs_out: __u32,
pub data_segs_out: __u32,
pub lost_out: __u32,
pub sacked_out: __u32,
pub bytes_received: __u64,
pub bytes_acked: __u64,
pub dsack_dups: __u32,
pub delivered: __u32,
pub delivered_ce: __u32,
pub icsk_retransmits: __u32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct bpf_sock_tuple {
pub __bindgen_anon_1: bpf_sock_tuple__bindgen_ty_1,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union bpf_sock_tuple__bindgen_ty_1 {
pub ipv4: bpf_sock_tuple__bindgen_ty_1__bindgen_ty_1,
pub ipv6: bpf_sock_tuple__bindgen_ty_1__bindgen_ty_2,
_bindgen_union_align: [u32; 9usize],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_sock_tuple__bindgen_ty_1__bindgen_ty_1 {
pub saddr: __be32,
pub daddr: __be32,
pub sport: __be16,
pub dport: __be16,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_sock_tuple__bindgen_ty_1__bindgen_ty_2 {
pub saddr: [__be32; 4usize],
pub daddr: [__be32; 4usize],
pub sport: __be16,
pub dport: __be16,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct xdp_md {
pub data: __u32,
pub data_end: __u32,
pub data_meta: __u32,
pub ingress_ifindex: __u32,
pub rx_queue_index: __u32,
pub egress_ifindex: __u32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct sk_msg_md {
pub __bindgen_anon_1: sk_msg_md__bindgen_ty_1,
pub __bindgen_anon_2: sk_msg_md__bindgen_ty_2,
pub family: __u32,
pub remote_ip4: __u32,
pub local_ip4: __u32,
pub remote_ip6: [__u32; 4usize],
pub local_ip6: [__u32; 4usize],
pub remote_port: __u32,
pub local_port: __u32,
pub size: __u32,
pub __bindgen_anon_3: sk_msg_md__bindgen_ty_3,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union sk_msg_md__bindgen_ty_1 {
pub data: *mut ::aya_bpf_cty::c_void,
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>,
_bindgen_union_align: u64,
}
impl sk_msg_md__bindgen_ty_1 {
#[inline]
pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 8usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default();
__bindgen_bitfield_unit
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union sk_msg_md__bindgen_ty_2 {
pub data_end: *mut ::aya_bpf_cty::c_void,
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>,
_bindgen_union_align: u64,
}
impl sk_msg_md__bindgen_ty_2 {
#[inline]
pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 8usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default();
__bindgen_bitfield_unit
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union sk_msg_md__bindgen_ty_3 {
pub sk: *mut bpf_sock,
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>,
_bindgen_union_align: u64,
}
impl sk_msg_md__bindgen_ty_3 {
#[inline]
pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 8usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default();
__bindgen_bitfield_unit
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct sk_reuseport_md {
pub __bindgen_anon_1: sk_reuseport_md__bindgen_ty_1,
pub __bindgen_anon_2: sk_reuseport_md__bindgen_ty_2,
pub len: __u32,
pub eth_protocol: __u32,
pub ip_protocol: __u32,
pub bind_inany: __u32,
pub hash: __u32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union sk_reuseport_md__bindgen_ty_1 {
pub data: *mut ::aya_bpf_cty::c_void,
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>,
_bindgen_union_align: u64,
}
impl sk_reuseport_md__bindgen_ty_1 {
#[inline]
pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 8usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default();
__bindgen_bitfield_unit
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union sk_reuseport_md__bindgen_ty_2 {
pub data_end: *mut ::aya_bpf_cty::c_void,
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>,
_bindgen_union_align: u64,
}
impl sk_reuseport_md__bindgen_ty_2 {
#[inline]
pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 8usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default();
__bindgen_bitfield_unit
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_map_info {
pub type_: __u32,
pub id: __u32,
pub key_size: __u32,
pub value_size: __u32,
pub max_entries: __u32,
pub map_flags: __u32,
pub name: [::aya_bpf_cty::c_char; 16usize],
pub ifindex: __u32,
pub btf_vmlinux_value_type_id: __u32,
pub netns_dev: __u64,
pub netns_ino: __u64,
pub btf_id: __u32,
pub btf_key_type_id: __u32,
pub btf_value_type_id: __u32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct bpf_sock_addr {
pub user_family: __u32,
pub user_ip4: __u32,
pub user_ip6: [__u32; 4usize],
pub user_port: __u32,
pub family: __u32,
pub type_: __u32,
pub protocol: __u32,
pub msg_src_ip4: __u32,
pub msg_src_ip6: [__u32; 4usize],
pub __bindgen_anon_1: bpf_sock_addr__bindgen_ty_1,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union bpf_sock_addr__bindgen_ty_1 {
pub sk: *mut bpf_sock,
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>,
_bindgen_union_align: u64,
}
impl bpf_sock_addr__bindgen_ty_1 {
#[inline]
pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 8usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default();
__bindgen_bitfield_unit
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct bpf_sock_ops {
pub op: __u32,
pub __bindgen_anon_1: bpf_sock_ops__bindgen_ty_1,
pub family: __u32,
pub remote_ip4: __u32,
pub local_ip4: __u32,
pub remote_ip6: [__u32; 4usize],
pub local_ip6: [__u32; 4usize],
pub remote_port: __u32,
pub local_port: __u32,
pub is_fullsock: __u32,
pub snd_cwnd: __u32,
pub srtt_us: __u32,
pub bpf_sock_ops_cb_flags: __u32,
pub state: __u32,
pub rtt_min: __u32,
pub snd_ssthresh: __u32,
pub rcv_nxt: __u32,
pub snd_nxt: __u32,
pub snd_una: __u32,
pub mss_cache: __u32,
pub ecn_flags: __u32,
pub rate_delivered: __u32,
pub rate_interval_us: __u32,
pub packets_out: __u32,
pub retrans_out: __u32,
pub total_retrans: __u32,
pub segs_in: __u32,
pub data_segs_in: __u32,
pub segs_out: __u32,
pub data_segs_out: __u32,
pub lost_out: __u32,
pub sacked_out: __u32,
pub sk_txhash: __u32,
pub bytes_received: __u64,
pub bytes_acked: __u64,
pub __bindgen_anon_2: bpf_sock_ops__bindgen_ty_2,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union bpf_sock_ops__bindgen_ty_1 {
pub args: [__u32; 4usize],
pub reply: __u32,
pub replylong: [__u32; 4usize],
_bindgen_union_align: [u32; 4usize],
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union bpf_sock_ops__bindgen_ty_2 {
pub sk: *mut bpf_sock,
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>,
_bindgen_union_align: u64,
}
impl bpf_sock_ops__bindgen_ty_2 {
#[inline]
pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 8usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default();
__bindgen_bitfield_unit
}
}
pub const BPF_SOCK_OPS_RTO_CB_FLAG: ::aya_bpf_cty::c_uint = 1;
pub const BPF_SOCK_OPS_RETRANS_CB_FLAG: ::aya_bpf_cty::c_uint = 2;
pub const BPF_SOCK_OPS_STATE_CB_FLAG: ::aya_bpf_cty::c_uint = 4;
pub const BPF_SOCK_OPS_RTT_CB_FLAG: ::aya_bpf_cty::c_uint = 8;
pub const BPF_SOCK_OPS_ALL_CB_FLAGS: ::aya_bpf_cty::c_uint = 15;
pub type _bindgen_ty_22 = ::aya_bpf_cty::c_uint;
pub const BPF_SOCK_OPS_VOID: ::aya_bpf_cty::c_uint = 0;
pub const BPF_SOCK_OPS_TIMEOUT_INIT: ::aya_bpf_cty::c_uint = 1;
pub const BPF_SOCK_OPS_RWND_INIT: ::aya_bpf_cty::c_uint = 2;
pub const BPF_SOCK_OPS_TCP_CONNECT_CB: ::aya_bpf_cty::c_uint = 3;
pub const BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: ::aya_bpf_cty::c_uint = 4;
pub const BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: ::aya_bpf_cty::c_uint = 5;
pub const BPF_SOCK_OPS_NEEDS_ECN: ::aya_bpf_cty::c_uint = 6;
pub const BPF_SOCK_OPS_BASE_RTT: ::aya_bpf_cty::c_uint = 7;
pub const BPF_SOCK_OPS_RTO_CB: ::aya_bpf_cty::c_uint = 8;
pub const BPF_SOCK_OPS_RETRANS_CB: ::aya_bpf_cty::c_uint = 9;
pub const BPF_SOCK_OPS_STATE_CB: ::aya_bpf_cty::c_uint = 10;
pub const BPF_SOCK_OPS_TCP_LISTEN_CB: ::aya_bpf_cty::c_uint = 11;
pub const BPF_SOCK_OPS_RTT_CB: ::aya_bpf_cty::c_uint = 12;
pub type _bindgen_ty_23 = ::aya_bpf_cty::c_uint;
pub const BPF_TCP_ESTABLISHED: ::aya_bpf_cty::c_uint = 1;
pub const BPF_TCP_SYN_SENT: ::aya_bpf_cty::c_uint = 2;
pub const BPF_TCP_SYN_RECV: ::aya_bpf_cty::c_uint = 3;
pub const BPF_TCP_FIN_WAIT1: ::aya_bpf_cty::c_uint = 4;
pub const BPF_TCP_FIN_WAIT2: ::aya_bpf_cty::c_uint = 5;
pub const BPF_TCP_TIME_WAIT: ::aya_bpf_cty::c_uint = 6;
pub const BPF_TCP_CLOSE: ::aya_bpf_cty::c_uint = 7;
pub const BPF_TCP_CLOSE_WAIT: ::aya_bpf_cty::c_uint = 8;
pub const BPF_TCP_LAST_ACK: ::aya_bpf_cty::c_uint = 9;
pub const BPF_TCP_LISTEN: ::aya_bpf_cty::c_uint = 10;
pub const BPF_TCP_CLOSING: ::aya_bpf_cty::c_uint = 11;
pub const BPF_TCP_NEW_SYN_RECV: ::aya_bpf_cty::c_uint = 12;
pub const BPF_TCP_MAX_STATES: ::aya_bpf_cty::c_uint = 13;
pub type _bindgen_ty_24 = ::aya_bpf_cty::c_uint;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_perf_event_value {
pub counter: __u64,
pub enabled: __u64,
pub running: __u64,
}
pub const BPF_DEVCG_ACC_MKNOD: ::aya_bpf_cty::c_uint = 1;
pub const BPF_DEVCG_ACC_READ: ::aya_bpf_cty::c_uint = 2;
pub const BPF_DEVCG_ACC_WRITE: ::aya_bpf_cty::c_uint = 4;
pub type _bindgen_ty_26 = ::aya_bpf_cty::c_uint;
pub const BPF_DEVCG_DEV_BLOCK: ::aya_bpf_cty::c_uint = 1;
pub const BPF_DEVCG_DEV_CHAR: ::aya_bpf_cty::c_uint = 2;
pub type _bindgen_ty_27 = ::aya_bpf_cty::c_uint;
pub const BPF_FIB_LOOKUP_DIRECT: ::aya_bpf_cty::c_uint = 1;
pub const BPF_FIB_LOOKUP_OUTPUT: ::aya_bpf_cty::c_uint = 2;
pub type _bindgen_ty_28 = ::aya_bpf_cty::c_uint;
pub const BPF_FIB_LKUP_RET_SUCCESS: ::aya_bpf_cty::c_uint = 0;
pub const BPF_FIB_LKUP_RET_BLACKHOLE: ::aya_bpf_cty::c_uint = 1;
pub const BPF_FIB_LKUP_RET_UNREACHABLE: ::aya_bpf_cty::c_uint = 2;
pub const BPF_FIB_LKUP_RET_PROHIBIT: ::aya_bpf_cty::c_uint = 3;
pub const BPF_FIB_LKUP_RET_NOT_FWDED: ::aya_bpf_cty::c_uint = 4;
pub const BPF_FIB_LKUP_RET_FWD_DISABLED: ::aya_bpf_cty::c_uint = 5;
pub const BPF_FIB_LKUP_RET_UNSUPP_LWT: ::aya_bpf_cty::c_uint = 6;
pub const BPF_FIB_LKUP_RET_NO_NEIGH: ::aya_bpf_cty::c_uint = 7;
pub const BPF_FIB_LKUP_RET_FRAG_NEEDED: ::aya_bpf_cty::c_uint = 8;
pub type _bindgen_ty_29 = ::aya_bpf_cty::c_uint;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct bpf_fib_lookup {
pub family: __u8,
pub l4_protocol: __u8,
pub sport: __be16,
pub dport: __be16,
pub tot_len: __u16,
pub ifindex: __u32,
pub __bindgen_anon_1: bpf_fib_lookup__bindgen_ty_1,
pub __bindgen_anon_2: bpf_fib_lookup__bindgen_ty_2,
pub __bindgen_anon_3: bpf_fib_lookup__bindgen_ty_3,
pub h_vlan_proto: __be16,
pub h_vlan_TCI: __be16,
pub smac: [__u8; 6usize],
pub dmac: [__u8; 6usize],
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union bpf_fib_lookup__bindgen_ty_1 {
pub tos: __u8,
pub flowinfo: __be32,
pub rt_metric: __u32,
_bindgen_union_align: u32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union bpf_fib_lookup__bindgen_ty_2 {
pub ipv4_src: __be32,
pub ipv6_src: [__u32; 4usize],
_bindgen_union_align: [u32; 4usize],
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union bpf_fib_lookup__bindgen_ty_3 {
pub ipv4_dst: __be32,
pub ipv6_dst: [__u32; 4usize],
_bindgen_union_align: [u32; 4usize],
}
pub const BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG: ::aya_bpf_cty::c_uint = 1;
pub const BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL: ::aya_bpf_cty::c_uint = 2;
pub const BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP: ::aya_bpf_cty::c_uint = 4;
pub type _bindgen_ty_30 = ::aya_bpf_cty::c_uint;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct bpf_flow_keys {
pub nhoff: __u16,
pub thoff: __u16,
pub addr_proto: __u16,
pub is_frag: __u8,
pub is_first_frag: __u8,
pub is_encap: __u8,
pub ip_proto: __u8,
pub n_proto: __be16,
pub sport: __be16,
pub dport: __be16,
pub __bindgen_anon_1: bpf_flow_keys__bindgen_ty_1,
pub flags: __u32,
pub flow_label: __be32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union bpf_flow_keys__bindgen_ty_1 {
pub __bindgen_anon_1: bpf_flow_keys__bindgen_ty_1__bindgen_ty_1,
pub __bindgen_anon_2: bpf_flow_keys__bindgen_ty_1__bindgen_ty_2,
_bindgen_union_align: [u32; 8usize],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_flow_keys__bindgen_ty_1__bindgen_ty_1 {
pub ipv4_src: __be32,
pub ipv4_dst: __be32,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_flow_keys__bindgen_ty_1__bindgen_ty_2 {
pub ipv6_src: [__u32; 4usize],
pub ipv6_dst: [__u32; 4usize],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_spin_lock {
pub val: __u32,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_sysctl {
pub write: __u32,
pub file_pos: __u32,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_pidns_info {
pub pid: __u32,
pub tgid: __u32,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_perf_event_data {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_redir_neigh {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct linux_binprm {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct pt_regs {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct sockaddr {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct tcphdr {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct seq_file {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct tcp6_sock {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct tcp_sock {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct tcp_timewait_sock {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct tcp_request_sock {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct udp6_sock {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct task_struct {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct path {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct btf_ptr {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct inode {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct socket {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct file {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bpf_map_def {
pub type_: ::aya_bpf_cty::c_uint,
pub key_size: ::aya_bpf_cty::c_uint,
pub value_size: ::aya_bpf_cty::c_uint,
pub max_entries: ::aya_bpf_cty::c_uint,
pub map_flags: ::aya_bpf_cty::c_uint,
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,4 @@
#![allow(dead_code, non_camel_case_types, non_snake_case)]
pub(crate) mod bindings;
pub(crate) mod helpers;

@ -0,0 +1,37 @@
use core::mem::{self, MaybeUninit};
use crate::{
bpf::generated::helpers as gen,
cty::{c_char, c_long, c_void},
};
pub use gen::*;
#[inline]
pub unsafe fn bpf_probe_read<T>(src: *const T) -> Result<T, c_long> {
let mut v: MaybeUninit<T> = MaybeUninit::uninit();
let ret = gen::bpf_probe_read(
v.as_mut_ptr() as *mut c_void,
mem::size_of::<T>() as u32,
src as *const c_void,
);
if ret < 0 {
return Err(ret);
}
Ok(v.assume_init())
}
#[inline]
pub fn bpf_get_current_comm() -> Result<[c_char; 16], ()> {
let mut comm: [c_char; 16usize] = [0; 16];
if unsafe { gen::bpf_get_current_comm(&mut comm as *mut _ as *mut c_void, 16u32) } == 0 {
Ok(comm)
} else {
Err(())
}
}
#[inline]
pub fn bpf_get_current_pid_tgid() -> u64 {
unsafe { gen::bpf_get_current_pid_tgid() }
}

@ -0,0 +1,4 @@
mod generated;
pub mod helpers;
pub use generated::bindings::*;

@ -0,0 +1,34 @@
#![no_std]
pub mod bpf;
pub mod maps;
pub mod programs;
pub use aya_bpf_cty as cty;
use bpf::helpers::{bpf_get_current_comm, bpf_get_current_pid_tgid};
use core::ffi::c_void;
use cty::c_char;
pub use aya_bpf_macros as macros;
pub const TASK_COMM_LEN: usize = 16;
pub trait BpfContext {
fn as_ptr(&self) -> *mut c_void;
#[inline]
fn command(&self) -> Result<[c_char; TASK_COMM_LEN], ()> {
bpf_get_current_comm()
}
#[inline]
fn pid(&self) -> u32 {
bpf_get_current_pid_tgid() as u32
}
#[inline]
fn tgid(&self) -> u32 {
(bpf_get_current_pid_tgid() >> 32) as u32
}
}

@ -0,0 +1,3 @@
pub mod perf_map;
pub use perf_map::PerfMap;

@ -0,0 +1,58 @@
use core::{marker::PhantomData, mem};
use crate::{
bpf::{
bpf_map_def, helpers::bpf_perf_event_output, BPF_F_CURRENT_CPU,
BPF_MAP_TYPE_PERF_EVENT_ARRAY,
},
BpfContext,
};
#[repr(transparent)]
pub struct PerfMap<T> {
def: bpf_map_def,
_t: PhantomData<T>,
}
impl<T> PerfMap<T> {
pub const fn new(flags: u32) -> PerfMap<T> {
PerfMap::with_max_entries(0, flags)
}
pub const fn with_max_entries(max_entries: u32, flags: u32) -> PerfMap<T> {
PerfMap {
def: bpf_map_def {
type_: BPF_MAP_TYPE_PERF_EVENT_ARRAY,
key_size: mem::size_of::<u32>() as u32,
value_size: mem::size_of::<u32>() as u32,
max_entries,
map_flags: flags,
},
_t: PhantomData,
}
}
pub fn output<C: BpfContext>(&mut self, ctx: &C, data: &T) {
self.output_at_index(ctx, None, data, 0)
}
pub fn output_at_index<C: BpfContext>(
&mut self,
ctx: &C,
index: Option<u32>,
data: &T,
flags: u32,
) {
let index = index.map(|i| (i as u64) << 32).unwrap_or(BPF_F_CURRENT_CPU);
let flags = index | flags as u64;
unsafe {
bpf_perf_event_output(
ctx.as_ptr(),
&mut self.def as *mut _ as *mut _,
flags,
data as *const _ as *mut _,
mem::size_of::<T>() as u64,
);
}
}
}

@ -0,0 +1,3 @@
pub mod probe;
pub use probe::ProbeContext;

@ -0,0 +1,21 @@
use core::ffi::c_void;
use crate::{bpf::pt_regs, BpfContext};
pub struct ProbeContext {
regs: *mut pt_regs,
}
impl ProbeContext {
pub fn new(ctx: *mut c_void) -> ProbeContext {
ProbeContext {
regs: ctx as *mut pt_regs,
}
}
}
impl BpfContext for ProbeContext {
fn as_ptr(&self) -> *mut c_void {
self.regs as *mut c_void
}
}

@ -0,0 +1,14 @@
[package]
name = "xtask"
version = "0.1.0"
authors = ["Alessandro Decina <alessandro.d@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
structopt = {version = "0.3", default-features = false }
anyhow = "1"
syn = {version = "1", features = ["visit-mut"] }
quote = "1"
proc-macro2 = "1"

@ -0,0 +1,140 @@
use std::{fs::File, io::Write, path::PathBuf, process::Command};
use anyhow::anyhow;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use structopt::StructOpt;
use syn::{
self, parse_str,
punctuated::Punctuated,
token::Comma,
visit_mut::{self, VisitMut},
AngleBracketedGenericArguments, ForeignItemStatic, GenericArgument, Ident, Item,
PathArguments::AngleBracketed,
Type,
};
#[derive(StructOpt)]
pub struct CodegenOptions {
#[structopt(long)]
libbpf_dir: PathBuf,
}
pub fn codegen(opts: CodegenOptions) -> Result<(), anyhow::Error> {
let dir = PathBuf::from("bpf/aya-bpf");
let generated = dir.join("src/bpf/generated");
let types: Vec<&str> = vec!["bpf_map_.*"];
let vars = vec!["BPF_.*", "bpf_.*"];
let mut cmd = Command::new("bindgen");
cmd.arg("--no-layout-tests")
.arg("--use-core")
.arg("--ctypes-prefix")
.arg("::aya_bpf_cty")
.arg("--default-enum-style")
.arg("consts")
.arg("--no-prepend-enum-name")
.arg(&*dir.join("include/aya_bpf_bindings.h").to_string_lossy());
for x in types {
cmd.arg("--whitelist-type").arg(x);
}
for x in vars {
cmd.arg("--whitelist-var").arg(x);
}
cmd.arg("--");
cmd.arg("-I").arg(opts.libbpf_dir.join("src"));
let output = cmd.output()?;
let bindings = std::str::from_utf8(&output.stdout)?;
if !output.status.success() {
eprintln!("{}", std::str::from_utf8(&output.stderr)?);
return Err(anyhow!("bindgen failed: {}", output.status));
}
// delete the helpers, then rewrite them in helpers.rs
let mut tree = parse_str::<syn::File>(bindings).unwrap();
let mut tx = RewriteBpfHelpers {
helpers: Vec::new(),
};
tx.visit_file_mut(&mut tree);
let filename = generated.join("bindings.rs");
{
let mut file = File::create(&filename)?;
write!(file, "{}", tree.to_token_stream())?;
}
Command::new("rustfmt").arg(filename).status()?;
let filename = generated.join("helpers.rs");
{
let mut file = File::create(&filename)?;
write!(file, "use crate::bpf::generated::bindings::*;")?;
for helper in &tx.helpers {
file.write(helper.as_bytes())?;
}
}
Command::new("rustfmt").arg(filename).status()?;
Ok(())
}
struct RewriteBpfHelpers {
helpers: Vec<String>,
}
impl VisitMut for RewriteBpfHelpers {
fn visit_item_mut(&mut self, item: &mut Item) {
visit_mut::visit_item_mut(self, item);
if let Item::ForeignMod(_) = item {
*item = Item::Verbatim(TokenStream::new())
}
}
fn visit_foreign_item_static_mut(&mut self, static_item: &mut ForeignItemStatic) {
if let Type::Path(path) = &*static_item.ty {
let ident = &static_item.ident;
let ident_str = ident.to_string();
let last = path.path.segments.last().unwrap();
let ty_ident = last.ident.to_string();
if ident_str.starts_with("bpf_") && ty_ident == "Option" {
let fn_ty = match &last.arguments {
AngleBracketed(AngleBracketedGenericArguments { args, .. }) => {
args.first().unwrap()
}
_ => panic!(),
};
let mut ty_s = quote! {
#[inline(always)]
pub #fn_ty
}
.to_string();
ty_s = ty_s.replace("fn (", &format!("fn {} (", ident_str));
let call_idx = self.helpers.len() + 1;
let args: Punctuated<Ident, Comma> = match fn_ty {
GenericArgument::Type(Type::BareFn(f)) => f
.inputs
.iter()
.map(|arg| arg.name.clone().unwrap().0)
.collect(),
_ => unreachable!(),
};
let body = quote! {
{
let f: #fn_ty = ::core::mem::transmute(#call_idx);
f(#args)
}
}
.to_string();
ty_s.push_str(&body);
let mut helper = ty_s;
if helper.contains("printk") {
helper = format!("/* {} */", helper);
}
self.helpers.push(helper);
}
}
}
}

@ -0,0 +1,22 @@
mod aya_bpf;
use structopt::StructOpt;
#[derive(StructOpt)]
pub struct Options {
#[structopt(subcommand)]
command: Command,
}
#[derive(StructOpt)]
enum Command {
#[structopt(name = "aya-bpf")]
AyaBpf(aya_bpf::CodegenOptions),
}
pub fn codegen(opts: Options) -> Result<(), anyhow::Error> {
use Command::*;
match opts.command {
AyaBpf(opts) => aya_bpf::codegen(opts),
}
}

@ -0,0 +1,29 @@
mod codegen;
use std::process::exit;
use structopt::StructOpt;
#[derive(StructOpt)]
pub struct Options {
#[structopt(subcommand)]
command: Command,
}
#[derive(StructOpt)]
enum Command {
Codegen(codegen::Options),
}
fn main() {
let opts = Options::from_args();
use Command::*;
let ret = match opts.command {
Codegen(opts) => codegen::codegen(opts),
};
if let Err(e) = ret {
eprintln!("{:#}", e);
exit(1);
}
}
Loading…
Cancel
Save