build(deps): update aya to latest main (#10424)

We haven't updated `aya` in a while. Unfortunately, the update is not without problems. For one, the logging infrastructure changed, requiring us to drop the error details from `xdp_adjust_head`. See https://github.com/aya-rs/aya/issues/1348. Two, the `tokio` feature flag got removed but luckily that can be worked around quite easily.

Resolves: #10344
This commit is contained in:
Thomas Eizinger
2025-09-23 07:45:59 +00:00
committed by GitHub
parent f09232e983
commit 94a56fc6bc
8 changed files with 174 additions and 107 deletions

159
rust/Cargo.lock generated
View File

@@ -45,7 +45,7 @@ dependencies = [
"bytestring",
"derive_more 2.0.1",
"encoding_rs",
"foldhash",
"foldhash 0.1.5",
"futures-core",
"http 0.2.12",
"httparse",
@@ -143,7 +143,7 @@ dependencies = [
"cfg-if",
"derive_more 2.0.1",
"encoding_rs",
"foldhash",
"foldhash 0.1.5",
"futures-core",
"futures-util",
"impl-more",
@@ -365,7 +365,7 @@ dependencies = [
"objc2-foundation",
"parking_lot",
"percent-encoding",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
"x11rb",
]
@@ -680,34 +680,33 @@ dependencies = [
[[package]]
name = "aya"
version = "0.13.1"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
dependencies = [
"assert_matches",
"aya-obj",
"bitflags 2.9.1",
"bytes",
"hashbrown 0.15.3",
"hashbrown 0.16.0",
"libc",
"log",
"object",
"object 0.37.3",
"once_cell",
"thiserror 2.0.16",
"tokio",
]
[[package]]
name = "aya-build"
version = "0.1.2"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
dependencies = [
"anyhow",
"cargo_metadata",
"cargo_metadata 0.22.0",
]
[[package]]
name = "aya-ebpf"
version = "0.1.1"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
dependencies = [
"aya-ebpf-bindings",
"aya-ebpf-cty",
@@ -718,7 +717,7 @@ dependencies = [
[[package]]
name = "aya-ebpf-bindings"
version = "0.1.1"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
dependencies = [
"aya-ebpf-cty",
]
@@ -726,12 +725,12 @@ dependencies = [
[[package]]
name = "aya-ebpf-cty"
version = "0.2.2"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
[[package]]
name = "aya-ebpf-macros"
version = "0.1.1"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
dependencies = [
"proc-macro2",
"proc-macro2-diagnostics",
@@ -742,20 +741,18 @@ dependencies = [
[[package]]
name = "aya-log"
version = "0.2.1"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
dependencies = [
"aya",
"aya-log-common",
"bytes",
"log",
"thiserror 2.0.16",
"tokio",
]
[[package]]
name = "aya-log-common"
version = "0.1.15"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
dependencies = [
"num_enum",
]
@@ -763,7 +760,7 @@ dependencies = [
[[package]]
name = "aya-log-ebpf"
version = "0.1.1"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
dependencies = [
"aya-ebpf",
"aya-log-common",
@@ -773,7 +770,7 @@ dependencies = [
[[package]]
name = "aya-log-ebpf-macros"
version = "0.1.0"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
dependencies = [
"aya-log-common",
"aya-log-parser",
@@ -785,7 +782,7 @@ dependencies = [
[[package]]
name = "aya-log-parser"
version = "0.1.13"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
dependencies = [
"aya-log-common",
]
@@ -793,12 +790,12 @@ dependencies = [
[[package]]
name = "aya-obj"
version = "0.2.1"
source = "git+https://github.com/aya-rs/aya#630a76711701a2f489f41d9d91076cc9bebb2675"
source = "git+https://github.com/aya-rs/aya#30182463bdb6cce592477e66659d5f66f846cfcf"
dependencies = [
"bytes",
"hashbrown 0.15.3",
"hashbrown 0.16.0",
"log",
"object",
"object 0.37.3",
"thiserror 2.0.16",
]
@@ -826,7 +823,7 @@ dependencies = [
"cfg-if",
"libc",
"miniz_oxide",
"object",
"object 0.36.7",
"rustc-demangle",
"windows-targets 0.52.6",
]
@@ -1105,11 +1102,11 @@ dependencies = [
[[package]]
name = "camino"
version = "1.1.9"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
checksum = "e1de8bc0aa9e9385ceb3bf0c152e3a9b9544f6c4a912c8ae504e80c1f0368603"
dependencies = [
"serde",
"serde_core",
]
[[package]]
@@ -1131,6 +1128,31 @@ dependencies = [
"serde",
]
[[package]]
name = "cargo-platform"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "122ec45a44b270afd1402f351b782c676b173e3c3fb28d86ff7ebfb4d86a4ee4"
dependencies = [
"serde",
]
[[package]]
name = "cargo-util-schemas"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dc1a6f7b5651af85774ae5a34b4e8be397d9cf4bc063b7e6dbd99a841837830"
dependencies = [
"semver",
"serde",
"serde-untagged",
"serde-value",
"thiserror 2.0.16",
"toml 0.8.22",
"unicode-xid",
"url",
]
[[package]]
name = "cargo_metadata"
version = "0.19.2"
@@ -1138,7 +1160,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba"
dependencies = [
"camino",
"cargo-platform",
"cargo-platform 0.1.9",
"semver",
"serde",
"serde_json",
"thiserror 2.0.16",
]
[[package]]
name = "cargo_metadata"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c3f56c207c76c07652489840ff98687dcf213de178ac0974660d6fefeaf5ec6"
dependencies = [
"camino",
"cargo-platform 0.3.1",
"cargo-util-schemas",
"semver",
"serde",
"serde_json",
@@ -2259,7 +2296,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
dependencies = [
"libc",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -2741,6 +2778,12 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "foldhash"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
[[package]]
name = "foreign-types"
version = "0.5.0"
@@ -3331,7 +3374,17 @@ checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash",
"foldhash 0.1.5",
]
[[package]]
name = "hashbrown"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
dependencies = [
"equivalent",
"foldhash 0.2.0",
]
[[package]]
@@ -4793,7 +4846,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [
"proc-macro-crate 3.3.0",
"proc-macro-crate 1.3.1",
"proc-macro2",
"quote",
"syn 2.0.106",
@@ -5018,6 +5071,15 @@ name = "object"
version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
"memchr",
]
[[package]]
name = "object"
version = "0.37.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
dependencies = [
"crc32fast",
"hashbrown 0.15.3",
@@ -5162,6 +5224,15 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "ordered-float"
version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
dependencies = [
"num-traits",
]
[[package]]
name = "ordered-stream"
version = "0.2.0"
@@ -5817,7 +5888,7 @@ dependencies = [
"once_cell",
"socket2 0.5.10",
"tracing",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -6207,7 +6278,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.4.15",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -6220,7 +6291,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.9.4",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -6664,6 +6735,16 @@ dependencies = [
"typeid",
]
[[package]]
name = "serde-value"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
dependencies = [
"ordered-float",
"serde",
]
[[package]]
name = "serde_assert"
version = "0.7.1"
@@ -7789,7 +7870,7 @@ checksum = "41a3852fdf9a4f8fbeaa63dc3e9a85284dd6ef7200751f0bd66ceee30c93f212"
dependencies = [
"anyhow",
"brotli",
"cargo_metadata",
"cargo_metadata 0.19.2",
"ctor",
"dunce",
"glob",
@@ -7852,7 +7933,7 @@ dependencies = [
"getrandom 0.3.3",
"once_cell",
"rustix 1.0.7",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -8627,7 +8708,7 @@ checksum = "c6d968cb62160c11f2573e6be724ef8b1b18a277aededd17033f8a912d73e2b4"
dependencies = [
"anyhow",
"camino",
"cargo_metadata",
"cargo_metadata 0.19.2",
"clap",
"uniffi_bindgen",
"uniffi_core",
@@ -8651,7 +8732,7 @@ dependencies = [
"anyhow",
"askama",
"camino",
"cargo_metadata",
"cargo_metadata 0.19.2",
"fs-err",
"glob",
"goblin",
@@ -9204,7 +9285,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.59.0",
"windows-sys 0.48.0",
]
[[package]]

View File

@@ -232,10 +232,13 @@ deny = [
skip = [
"base64",
"bitflags",
"cargo-platform",
"cargo_metadata",
"core-foundation",
"core-graphics",
"core-graphics-types",
"derive_more",
"foldhash",
"getrandom",
"hashbrown",
"heck",
@@ -244,6 +247,7 @@ skip = [
"libloading",
"linux-raw-sys",
"nix",
"object",
"phf",
"phf_codegen",
"phf_generator",

View File

@@ -34,13 +34,13 @@ pub fn handle_turn(ctx: aya_ebpf::programs::XdpContext) -> u32 {
| Error::UdpChecksumMissing
| Error::Ipv4PacketWithOptions),
) => {
debug!(&ctx, target: "eBPF", "^^^ pass packet to userspace: {}", e);
debug!(&ctx, target: "eBPF", "^^^ pass packet to userspace: {}", e.as_str());
xdp_action::XDP_PASS
}
// In a double symmetric NAT setup, it is easily possible for packets to arrive from IPs that don't have channel bindings.
Err(e @ Error::NoEntry(_)) => {
debug!(&ctx,target: "eBPF", "XXX drop packet: {}", e);
debug!(&ctx,target: "eBPF", "XXX drop packet: {}", e.as_str());
xdp_action::XDP_DROP
}
@@ -48,9 +48,9 @@ pub fn handle_turn(ctx: aya_ebpf::programs::XdpContext) -> u32 {
e @ (Error::ArrayIndexOutOfBounds
| Error::IpAddrUnset
| Error::BadChannelDataLength
| Error::XdpAdjustHeadFailed(_)),
| Error::XdpAdjustHeadFailed),
) => {
warn!(&ctx,target: "eBPF", "XXX drop packet: {}", e);
warn!(&ctx,target: "eBPF", "XXX drop packet: {}", e.as_str());
xdp_action::XDP_DROP
}

View File

@@ -7,7 +7,7 @@ pub fn adjust_head(ctx: &XdpContext, size: i32) -> Result<(), Error> {
// SAFETY: The attach mode and NIC driver support headroom adjustment by `size` bytes.
let ret = unsafe { bpf_xdp_adjust_head(ctx.ctx, size) };
if ret < 0 {
return Err(Error::XdpAdjustHeadFailed(ret));
return Err(Error::XdpAdjustHeadFailed);
}
Ok(())

View File

@@ -1,5 +1,3 @@
use core::num::NonZeroUsize;
#[derive(Debug, Clone, Copy)]
pub enum Error {
ArrayIndexOutOfBounds,
@@ -14,7 +12,7 @@ pub enum Error {
NotAChannelDataMessage,
BadChannelDataLength,
NoEntry(SupportedChannel),
XdpAdjustHeadFailed(i64),
XdpAdjustHeadFailed,
}
#[derive(Debug, Clone, Copy)]
@@ -25,11 +23,10 @@ pub enum SupportedChannel {
Chan6ToUdp,
}
impl aya_log_ebpf::WriteToBuf for Error {
impl Error {
#[inline(always)]
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
// Use a simpler match structure to help the verifier
let msg = match self {
pub fn as_str(&self) -> &'static str {
match self {
Error::ArrayIndexOutOfBounds => "Array index is out of bounds",
Error::IpAddrUnset => "IP address has not been configured",
Error::UdpChecksumMissing => "UDP checksum is missing",
@@ -47,54 +44,9 @@ impl aya_log_ebpf::WriteToBuf for Error {
SupportedChannel::Udp6ToChan => "No entry in UDPv6 to channel IPv4 or IPv6 map",
SupportedChannel::Chan6ToUdp => "No entry in channel IPv6 to UDPv4 or UDPv6 map",
},
Error::XdpAdjustHeadFailed(ret) => {
// Handle this case separately to avoid complex control flow
let mut written = 0;
written += "Failed to adjust tail: ".write(buf)?.get();
written += errno_to_str(ret).write(buf)?.get();
return NonZeroUsize::new(written);
}
};
msg.write(buf)
Error::XdpAdjustHeadFailed => "Failed to adjust tail",
}
}
}
impl aya_log_ebpf::macro_support::DefaultFormatter for Error {}
/// Helper function to map Linux/eBPF error codes to human-readable strings
/// This avoids integer formatting which can cause pointer arithmetic verifier issues
#[inline(always)]
fn errno_to_str(errno: i64) -> &'static str {
match errno {
-1 => "EPERM (Operation not permitted)",
-2 => "ENOENT (No such file or directory)",
-3 => "ESRCH (No such process)",
-4 => "EINTR (Interrupted system call)",
-5 => "EIO (I/O error)",
-6 => "ENXIO (No such device or address)",
-7 => "E2BIG (Argument list too long)",
-8 => "ENOEXEC (Exec format error)",
-9 => "EBADF (Bad file number)",
-10 => "ECHILD (No child processes)",
-11 => "EAGAIN (Try again)",
-12 => "ENOMEM (Out of memory)",
-13 => "EACCES (Permission denied)",
-14 => "EFAULT (Bad address)",
-16 => "EBUSY (Device or resource busy)",
-17 => "EEXIST (File exists)",
-19 => "ENODEV (No such device)",
-22 => "EINVAL (Invalid argument)",
-24 => "EMFILE (Too many open files)",
-28 => "ENOSPC (No space left on device)",
-32 => "EPIPE (Broken pipe)",
-34 => "ERANGE (Math result not representable)",
-61 => "ENODATA (No data available)",
-75 => "EOVERFLOW (Value too large for defined data type)",
-84 => "EILSEQ (Illegal byte sequence)",
-90 => "EMSGSIZE (Message too long)",
-95 => "ENOTSUP (Operation not supported)",
-105 => "ENOBUFS (No buffer space available)",
_ => "Unknown error",
}
}

View File

@@ -50,7 +50,7 @@ url = { workspace = true }
uuid = { workspace = true, features = ["v4"] }
[target.'cfg(target_os = "linux")'.dependencies]
aya = { workspace = true, features = ["tokio"] }
aya = { workspace = true }
aya-log = { workspace = true }
ebpf-shared = { workspace = true, features = ["std"] }

View File

@@ -9,7 +9,7 @@ fn main() -> anyhow::Result<()> {
.context("MetadataCommand::exec")?
.packages
.into_iter()
.find(|Package { name, .. }| name == "ebpf-turn-router")
.find(|Package { name, .. }| name.as_str() == "ebpf-turn-router")
.context("`ebpf-turn-router` package not found")?;
aya_build::build_ebpf(

View File

@@ -1,9 +1,12 @@
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
use std::{
io,
net::{Ipv4Addr, Ipv6Addr, SocketAddr},
};
use anyhow::{Context as _, Result};
use aya::{
Pod,
maps::{AsyncPerfEventArray, HashMap, MapData, PerCpuArray, PerCpuValues},
maps::{HashMap, MapData, PerCpuArray, PerCpuValues, PerfEventArray},
programs::{Xdp, XdpFlags},
};
use aya_log::EbpfLogger;
@@ -12,6 +15,7 @@ use ebpf_shared::{
ClientAndChannelV4, ClientAndChannelV6, PortAndPeerV4, PortAndPeerV6, StatsEvent,
};
use stun_codec::rfc5766::attributes::ChannelNumber;
use tokio::io::{Interest, unix::AsyncFd};
use crate::ebpf::AttachMode;
@@ -28,7 +32,7 @@ pub struct Program {
ebpf: aya::Ebpf,
#[expect(dead_code, reason = "We are just keeping it alive.")]
stats: AsyncPerfEventArray<MapData>,
stats: PerfEventArray<MapData>,
}
impl Program {
@@ -44,7 +48,22 @@ impl Program {
env!("OUT_DIR"),
"/ebpf-turn-router-main"
)))?;
let _ = EbpfLogger::init(&mut ebpf);
let logger = EbpfLogger::init(&mut ebpf)?;
let mut logger = AsyncFd::with_interest(logger, Interest::READABLE)?;
tokio::task::spawn(async move {
loop {
let mut guard = match logger.readable_mut().await {
Ok(guard) => guard,
Err(e) => {
tracing::warn!("Failed to wait for logger to be readable: {e}");
return;
}
};
guard.get_inner_mut().flush();
guard.clear_ready();
}
});
let program: &mut Xdp = ebpf
.program_mut("handle_turn")
.context("No program")?
@@ -60,7 +79,7 @@ impl Program {
.attach(interface, xdp_flags)
.with_context(|| format!("Failed to attached to interface {interface}"))?;
let mut stats = AsyncPerfEventArray::try_from(
let mut stats = PerfEventArray::try_from(
ebpf.take_map("STATS")
.context("`STATS` perf array not found")?,
)?;
@@ -76,7 +95,8 @@ impl Program {
.context("Failed to determine number of CPUs")?
{
// open a separate perf buffer for each cpu
let mut stats_array_buf = stats.open(cpu_id, Some(PAGE_COUNT))?;
let stats_array_buf = stats.open(cpu_id, Some(PAGE_COUNT))?;
let mut fd = AsyncFd::new(stats_array_buf)?;
tracing::debug!(%cpu_id, "Subscribing to stats events from eBPF kernel");
@@ -90,7 +110,17 @@ impl Program {
.collect::<Vec<_>>();
loop {
let events = match stats_array_buf.read_events(&mut buffers).await {
let events = fd
.async_io_mut(Interest::READABLE, |fd| {
if !fd.readable() {
return Err(io::Error::from(io::ErrorKind::WouldBlock));
}
fd.read_events(&mut buffers).map_err(io::Error::other)
})
.await;
let events = match events {
Ok(events) => events,
Err(e) => {
tracing::warn!("Failed to read perf events: {e}");