Add zerocopy derives to common Pod types for compile-time layout verification

Replace unsafe-only Pod marker pattern with zerocopy derive macros on
FlowStats, AddrPortV4, and AddrPortV6. The compiler now verifies at
build time that these types have no padding, no uninit bytes, and no
interior mutability — invariants previously only asserted by hand via
`unsafe impl Pod`. The aya Pod impls remain unchanged since aya does
not provide a blanket impl over zerocopy traits.

zerocopy is gated to the `user` feature so the kernel (eBPF) build is
unaffected.

https://claude.ai/code/session_0138PxtKH73hqxv7h1oaoSdS
This commit is contained in:
Claude 2026-06-16 02:56:31 +00:00
parent 446ff44192
commit b847374341
No known key found for this signature in database
5 changed files with 11 additions and 2 deletions

1
Cargo.lock generated
View File

@ -470,6 +470,7 @@ dependencies = [
"aya-ebpf",
"network-types",
"serde",
"zerocopy 0.8.33",
]
[[package]]

View File

@ -12,6 +12,7 @@ cargo_metadata = { version = "0.23.1", default-features = false }
libc = { version = "0.2.159", default-features = false }
network-types = "0.1.0"
serde = { version = "1.0.215", features = ["derive"] }
zerocopy = { version = "0.8", default-features = false, features = ["derive"] }
xsk-rs = { version = "0.8.0", default-features = false }
[profile.dev]

View File

@ -5,13 +5,14 @@ edition = "2024"
[features]
default = []
user = ["aya", "serde"]
user = ["aya", "serde", "dep:zerocopy"]
kernel = ["aya-ebpf"]
[dependencies]
aya = { workspace = true, optional = true }
aya-ebpf = { workspace = true, optional = true }
serde = { workspace = true, optional = true }
zerocopy = { workspace = true, optional = true }
network-types = { workspace = true }
[lib]

View File

@ -2,10 +2,12 @@
use aya::Pod;
#[cfg(feature = "user")]
use serde::Serialize;
#[cfg(feature = "user")]
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
#[repr(C, align(8))]
#[derive(Clone, Copy)]
#[cfg_attr(feature = "user", derive(Serialize, Debug))]
#[cfg_attr(feature = "user", derive(Serialize, Debug, FromBytes, IntoBytes, KnownLayout, Immutable))]
pub struct FlowStats {
pub bytes: u64,
pub packets: u64,

View File

@ -1,5 +1,7 @@
#[cfg(feature = "user")]
use aya::Pod;
#[cfg(feature = "user")]
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
pub type IPv4 = u32;
pub type IPv6 = u128;
@ -7,6 +9,7 @@ pub type Port = u16;
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "user", derive(FromBytes, IntoBytes, KnownLayout, Immutable))]
pub struct AddrPortV4([u8; 8]);
impl AddrPortV4 {
@ -43,6 +46,7 @@ unsafe impl Pod for AddrPortV4 {}
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "user", derive(FromBytes, IntoBytes, KnownLayout, Immutable))]
pub struct AddrPortV6([u8; 32]);
impl AddrPortV6 {