6
aya-playground-ebpf/.cargo/config.toml
Normal file
6
aya-playground-ebpf/.cargo/config.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[build]
|
||||
target-dir = "../target"
|
||||
target = "bpfel-unknown-none"
|
||||
|
||||
[unstable]
|
||||
build-std = ["core"]
|
||||
4
aya-playground-ebpf/.vim/coc-settings.json
Normal file
4
aya-playground-ebpf/.vim/coc-settings.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"rust-analyzer.cargo.target": "bpfel-unknown-none",
|
||||
"rust-analyzer.checkOnSave.allTargets": false
|
||||
}
|
||||
4
aya-playground-ebpf/.vscode/settings.json
vendored
Normal file
4
aya-playground-ebpf/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"rust-analyzer.cargo.target": "bpfel-unknown-none",
|
||||
"rust-analyzer.checkOnSave.allTargets": false
|
||||
}
|
||||
33
aya-playground-ebpf/Cargo.toml
Normal file
33
aya-playground-ebpf/Cargo.toml
Normal file
@@ -0,0 +1,33 @@
|
||||
[package]
|
||||
name = "aya-playground-ebpf"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
aya-bpf = { git = "https://github.com/aya-rs/aya" }
|
||||
aya-log-ebpf = { git = "https://github.com/aya-rs/aya" }
|
||||
aya-playground-common = { path = "../aya-playground-common" }
|
||||
network-types = "0.0.4"
|
||||
|
||||
[[bin]]
|
||||
name = "aya-playground"
|
||||
path = "src/main.rs"
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 3
|
||||
debug = false
|
||||
debug-assertions = false
|
||||
overflow-checks = false
|
||||
lto = true
|
||||
panic = "abort"
|
||||
incremental = false
|
||||
codegen-units = 1
|
||||
rpath = false
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
panic = "abort"
|
||||
codegen-units = 1
|
||||
|
||||
[workspace]
|
||||
members = []
|
||||
32
aya-playground-ebpf/Cargo.toml~
Normal file
32
aya-playground-ebpf/Cargo.toml~
Normal file
@@ -0,0 +1,32 @@
|
||||
[package]
|
||||
name = "aya-playground-ebpf"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
aya-bpf = { git = "https://github.com/aya-rs/aya" }
|
||||
aya-log-ebpf = { git = "https://github.com/aya-rs/aya" }
|
||||
aya-playground-common = { path = "../aya-playground-common" }
|
||||
|
||||
[[bin]]
|
||||
name = "aya-playground"
|
||||
path = "src/main.rs"
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 3
|
||||
debug = false
|
||||
debug-assertions = false
|
||||
overflow-checks = false
|
||||
lto = true
|
||||
panic = "abort"
|
||||
incremental = false
|
||||
codegen-units = 1
|
||||
rpath = false
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
panic = "abort"
|
||||
codegen-units = 1
|
||||
|
||||
[workspace]
|
||||
members = []
|
||||
13
aya-playground-ebpf/rust-toolchain.toml
Normal file
13
aya-playground-ebpf/rust-toolchain.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[toolchain]
|
||||
channel = "nightly"
|
||||
# The source code of rustc, provided by the rust-src component, is needed for
|
||||
# building eBPF programs.
|
||||
components = [
|
||||
"cargo",
|
||||
"clippy",
|
||||
"rust-docs",
|
||||
"rust-src",
|
||||
"rust-std",
|
||||
"rustc",
|
||||
"rustfmt",
|
||||
]
|
||||
67
aya-playground-ebpf/src/main.rs
Normal file
67
aya-playground-ebpf/src/main.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use aya_bpf::{bindings::xdp_action, macros::xdp, programs::XdpContext};
|
||||
use aya_log_ebpf::info;
|
||||
|
||||
use core::mem;
|
||||
use network_types::{
|
||||
eth::{EthHdr, EtherType},
|
||||
ip::{IpProto, Ipv4Hdr},
|
||||
tcp::TcpHdr,
|
||||
udp::UdpHdr,
|
||||
};
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
unsafe { core::hint::unreachable_unchecked() }
|
||||
}
|
||||
|
||||
#[xdp]
|
||||
pub fn aya_playground(ctx: XdpContext) -> u32 {
|
||||
match try_xdp_firewall(ctx) {
|
||||
Ok(ret) => ret,
|
||||
Err(_) => xdp_action::XDP_ABORTED,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ptr_at<T>(ctx: &XdpContext, offset: usize) -> Result<*const T, ()> {
|
||||
let start = ctx.data();
|
||||
let end = ctx.data_end();
|
||||
let len = mem::size_of::<T>();
|
||||
|
||||
if start + offset + len > end {
|
||||
Err(())
|
||||
} else {
|
||||
Ok((start + offset) as *const T)
|
||||
}
|
||||
}
|
||||
|
||||
fn try_xdp_firewall(ctx: XdpContext) -> Result<u32, ()> {
|
||||
let ethhdr: *const EthHdr = ptr_at(&ctx, 0)?;
|
||||
// Only pass Ipv4 along pipeline, ALLOW rest
|
||||
match unsafe { (*ethhdr).ether_type } {
|
||||
EtherType::Ipv4 => {}
|
||||
_ => return Ok(xdp_action::XDP_PASS),
|
||||
}
|
||||
|
||||
let ipv4hdr: *const Ipv4Hdr = ptr_at(&ctx, EthHdr::LEN)?;
|
||||
let source_addr = u32::from_be(unsafe { (*ipv4hdr).src_addr });
|
||||
|
||||
let source_port = match unsafe { (*ipv4hdr).proto } {
|
||||
IpProto::Tcp => {
|
||||
let tcphdr: *const TcpHdr = ptr_at(&ctx, Ipv4Hdr::LEN)?;
|
||||
u16::from_be(unsafe { (*tcphdr).source })
|
||||
}
|
||||
IpProto::Udp => {
|
||||
let udphdr: *const UdpHdr = ptr_at(&ctx, Ipv4Hdr::LEN)?;
|
||||
u16::from_be(unsafe { (*udphdr).source })
|
||||
}
|
||||
_ => return Err(()),
|
||||
};
|
||||
|
||||
info!(&ctx, "SRC IP: {:i}, SRC PORT: {}", source_addr, source_port);
|
||||
|
||||
Ok(xdp_action::XDP_PASS)
|
||||
}
|
||||
Reference in New Issue
Block a user