-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: iGxnon <[email protected]>
- Loading branch information
Showing
9 changed files
with
248 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
[target.'cfg(all())'] | ||
rustflags = ["--cfg", "tokio_unstable"] | ||
|
||
[alias] | ||
x = "run --package xtask --" | ||
xtask = "run --package xtask --" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ default: | |
just --list | ||
|
||
fix: | ||
cargo fmt | ||
cargo fmt --all | ||
cargo sort --workspace | ||
cargo machete --fix | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[build] | ||
target = ["bpfeb-unknown-none", "bpfel-unknown-none"] | ||
|
||
[unstable] | ||
build-std = ["core"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
[package] | ||
name = "ebpf" | ||
version = "0.1.0" | ||
publish = false | ||
edition = { workspace = true } | ||
license = { workspace = true } | ||
authors = { workspace = true } | ||
homepage = { workspace = true } | ||
repository = { workspace = true } | ||
categories = { workspace = true } | ||
keywords = { workspace = true } | ||
|
||
[dependencies] | ||
# These crates are not published so use a git dependency for now. See https://github.com/aya-rs/aya/issues/464 | ||
aya-bpf = { git = "https://github.com/aya-rs/aya", tag = "aya-v0.12.0" } | ||
aya-log-ebpf = { git = "https://github.com/aya-rs/aya", tag = "aya-v0.12.0" } | ||
|
||
[features] | ||
default = [] | ||
trace = [] | ||
|
||
[[bin]] | ||
name = "raknet-xdp-ebpf" | ||
path = "src/main.rs" | ||
|
||
[lints] | ||
workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#![no_std] | ||
#![no_main] | ||
|
||
use aya_bpf::bindings::xdp_action; | ||
use aya_bpf::macros::{map, xdp}; | ||
use aya_bpf::maps::{HashMap, XskMap}; | ||
use aya_bpf::programs::XdpContext; | ||
|
||
// Never panic | ||
#[cfg(not(test))] | ||
#[panic_handler] | ||
fn panic(_info: &core::panic::PanicInfo) -> ! { | ||
unsafe { core::hint::unreachable_unchecked() } | ||
} | ||
|
||
#[map] | ||
static XDP_SOCKETS: XskMap = XskMap::with_max_entries(1024, 0); | ||
|
||
#[map] | ||
static XDP_PORTS: HashMap<u16, u8> = HashMap::with_max_entries(1024, 0); | ||
|
||
#[xdp] | ||
pub fn raknet_xdp(ctx: XdpContext) -> u32 { | ||
let action = redirect_udp(&ctx); | ||
|
||
#[cfg(feature = "trace")] | ||
{ | ||
use aya_log_ebpf as log; | ||
|
||
match action { | ||
xdp_action::XDP_DROP => log::trace!(&ctx, "ACTION: DROP"), | ||
xdp_action::XDP_PASS => log::trace!(&ctx, "ACTION: PASS"), | ||
xdp_action::XDP_REDIRECT => log::trace!(&ctx, "ACTION: REDIRECT"), | ||
xdp_action::XDP_ABORTED => log::trace!(&ctx, "ACTION: ABORTED"), | ||
_ => (), | ||
} | ||
} | ||
|
||
action | ||
} | ||
|
||
fn redirect_udp(ctx: &XdpContext) -> u32 { | ||
let start = ctx.data() as *mut u8; | ||
let len = ctx.data_end() - ctx.data(); | ||
// Safety: It was checked to be in XdpContext | ||
let _data = unsafe { core::slice::from_raw_parts_mut(start, len) }; | ||
// TODO: parse data and check whether it is a valid UDP frame | ||
|
||
xdp_action::XDP_PASS | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "raknet-xdp" | ||
version = "0.1.0" | ||
edition = { workspace = true } | ||
license = { workspace = true } | ||
authors = { workspace = true } | ||
homepage = { workspace = true } | ||
repository = { workspace = true } | ||
categories = { workspace = true } | ||
keywords = { workspace = true } | ||
|
||
[dependencies] | ||
aya = { version = "0.12", default-features = false } | ||
|
||
[dev-dependencies] | ||
env_logger = "0.11" | ||
|
||
[build-dependencies] | ||
cargo_metadata = "0.18" | ||
|
||
[lints] | ||
workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
use std::io::{BufRead, BufReader}; | ||
use std::path::PathBuf; | ||
use std::process::{Child, Command, Stdio}; | ||
use std::{env, fs}; | ||
|
||
use cargo_metadata::{ | ||
Artifact, CompilerMessage, Message, Metadata, MetadataCommand, Package, Target, | ||
}; | ||
|
||
const RECOMPILE_OPT: &str = "RAK_XDP_EBPF_COMPILE"; | ||
const TRACE_OPT: &str = "RAK_XDP_EBFP_TRACE"; | ||
|
||
fn main() { | ||
println!("cargo:rerun-if-env-changed={}", RECOMPILE_OPT); | ||
println!("cargo:rerun-if-env-changed={}", TRACE_OPT); | ||
|
||
let enable_trace = env::var(TRACE_OPT).unwrap_or_default(); | ||
let out_dir = env::var_os("OUT_DIR").unwrap(); | ||
let out_dir = PathBuf::from(out_dir); | ||
let endian = env::var_os("CARGO_CFG_TARGET_ENDIAN").unwrap(); | ||
let target = if endian == "big" { | ||
"bpfeb-unknown-none" | ||
} else if endian == "little" { | ||
"bpfel-unknown-none" | ||
} else { | ||
panic!("unsupported endian={:?}", endian) | ||
}; | ||
let Metadata { packages, .. } = MetadataCommand::new().no_deps().exec().unwrap(); | ||
let ebpf_package = packages | ||
.into_iter() | ||
.find(|Package { name, .. }| name == "ebpf") | ||
.unwrap(); | ||
let Package { manifest_path, .. } = ebpf_package; | ||
let ebpf_dir = manifest_path.parent().unwrap(); | ||
|
||
println!("cargo:rerun-if-changed={}", ebpf_dir.as_str()); | ||
|
||
// build all bins in ebpf | ||
let mut cmd = Command::new("cargo"); | ||
cmd.current_dir(ebpf_dir); | ||
cmd.args([ | ||
"build", | ||
"-Z", | ||
"build-std=core", | ||
"--bins", | ||
"--message-format=json", | ||
"--release", | ||
"--target", | ||
target, | ||
]); | ||
if matches!(enable_trace.to_lowercase().as_str(), "1" | "on" | "true") { | ||
cmd.args(["--features", "trace"]); | ||
} | ||
|
||
let mut child = cmd | ||
.stdout(Stdio::piped()) | ||
.stderr(Stdio::piped()) | ||
.spawn() | ||
.unwrap_or_else(|err| panic!("failed to spawn {cmd:?}: {err}")); | ||
let Child { stdout, stderr, .. } = &mut child; | ||
|
||
// Trampoline stdout to cargo warnings. | ||
let stderr = BufReader::new(stderr.take().unwrap()); | ||
let stderr = std::thread::spawn(move || { | ||
for line in stderr.lines() { | ||
let line = line.unwrap(); | ||
println!("cargo:warning={line}"); | ||
} | ||
}); | ||
|
||
let stdout = BufReader::new(stdout.take().unwrap()); | ||
let mut executables = Vec::new(); | ||
for message in Message::parse_stream(stdout) { | ||
#[allow(clippy::collapsible_match)] | ||
match message.expect("valid JSON") { | ||
Message::CompilerArtifact(Artifact { | ||
executable, | ||
target: Target { name, .. }, | ||
.. | ||
}) => { | ||
if let Some(executable) = executable { | ||
executables.push((name, executable.into_std_path_buf())); | ||
} | ||
} | ||
Message::CompilerMessage(CompilerMessage { message: msg, .. }) => { | ||
for line in msg.rendered.unwrap_or_default().split('\n') { | ||
println!("cargo:warning={line}"); | ||
} | ||
} | ||
Message::TextLine(line) => { | ||
println!("cargo:warning={line}"); | ||
} | ||
_ => {} | ||
} | ||
} | ||
|
||
let status = child | ||
.wait() | ||
.unwrap_or_else(|err| panic!("failed to wait for {cmd:?}: {err}")); | ||
assert_eq!(status.code(), Some(0), "{cmd:?} failed: {status:?}"); | ||
|
||
stderr.join().map_err(std::panic::resume_unwind).unwrap(); | ||
|
||
// copy to $OUT_DIR | ||
for (name, binary) in executables { | ||
let dst = out_dir.join(name); | ||
let _: u64 = fs::copy(&binary, &dst) | ||
.unwrap_or_else(|err| panic!("failed to copy {binary:?} to {dst:?}: {err}")); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
use aya::include_bytes_aligned; | ||
|
||
pub const DEFAULT_PROGRAM: &[u8] = | ||
include_bytes_aligned!(concat!(env!("OUT_DIR"), "/raknet-xdp-ebpf")); | ||
pub const DEFAULT_PROGRAM_NAME: &str = "raknet_xdp"; |