Skip to main content

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};