orb8_common/lib.rs
1//! Shared types between eBPF (kernel) and userspace
2//!
3//! This crate defines event structures that must be:
4//! - `#[repr(C)]` for stable memory layout
5//! - `no_std` compatible for eBPF
6//! - Shared between kernel probes and userspace agent
7
8#![cfg_attr(not(feature = "userspace"), no_std)]
9
10// IP address handling assumes little-endian architecture throughout.
11// The eBPF probe reads IPs via native pointer dereference and userspace
12// parses with from_le_bytes — these are only equivalent on LE systems.
13#[cfg(not(target_endian = "little"))]
14compile_error!(
15 "orb8 requires a little-endian target (x86_64, aarch64). \
16 IP address byte order handling is not compatible with big-endian systems."
17);
18
19/// Simple packet event (legacy, kept for backward compatibility)
20#[repr(C)]
21#[derive(Clone, Copy, Debug)]
22#[cfg_attr(feature = "userspace", derive(PartialEq, Eq))]
23pub struct PacketEvent {
24 pub timestamp_ns: u64,
25 pub packet_len: u32,
26 pub _padding: u32,
27}
28
29/// Network flow event with full 5-tuple and container identification
30///
31/// Layout (32 bytes total, 8-byte aligned):
32/// - timestamp_ns: Kernel timestamp in nanoseconds
33/// - cgroup_id: Container cgroup ID for pod correlation (0 for TC classifiers)
34/// - src_ip: Source IPv4 address (first octet in LSB, as read from TC classifier)
35/// - dst_ip: Destination IPv4 address (first octet in LSB, as read from TC classifier)
36/// - src_port: Source port (host byte order)
37/// - dst_port: Destination port (host byte order)
38/// - protocol: IP protocol (6=TCP, 17=UDP, 1=ICMP)
39/// - direction: Traffic direction (0=ingress, 1=egress)
40/// - packet_len: Packet size in bytes
41///
42/// Note: IP addresses are stored with first octet in LSB position. For example,
43/// 10.0.0.5 is stored as 0x0500000A. Use `from_le_bytes` when parsing IP strings.
44#[repr(C)]
45#[derive(Clone, Copy, Debug)]
46#[cfg_attr(feature = "userspace", derive(PartialEq, Eq))]
47pub struct NetworkFlowEvent {
48 pub timestamp_ns: u64,
49 pub cgroup_id: u64,
50 pub src_ip: u32,
51 pub dst_ip: u32,
52 pub src_port: u16,
53 pub dst_port: u16,
54 pub protocol: u8,
55 pub direction: u8,
56 pub packet_len: u16,
57}
58
59/// Traffic direction constants
60pub mod direction {
61 pub const INGRESS: u8 = 0;
62 pub const EGRESS: u8 = 1;
63}
64
65/// IP protocol constants
66pub mod protocol {
67 pub const ICMP: u8 = 1;
68 pub const TCP: u8 = 6;
69 pub const UDP: u8 = 17;
70}
71
72#[cfg(feature = "userspace")]
73const _: () = {
74 assert!(
75 core::mem::size_of::<PacketEvent>() == 16,
76 "PacketEvent must be exactly 16 bytes"
77 );
78 assert!(
79 core::mem::align_of::<PacketEvent>() == 8,
80 "PacketEvent must be 8-byte aligned"
81 );
82};
83
84#[cfg(feature = "userspace")]
85const _: () = {
86 assert!(
87 core::mem::size_of::<NetworkFlowEvent>() == 32,
88 "NetworkFlowEvent must be exactly 32 bytes"
89 );
90 assert!(
91 core::mem::align_of::<NetworkFlowEvent>() == 8,
92 "NetworkFlowEvent must be 8-byte aligned"
93 );
94};