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/// Simple packet event (legacy, kept for backward compatibility)
11#[repr(C)]
12#[derive(Clone, Copy, Debug)]
13#[cfg_attr(feature = "userspace", derive(PartialEq, Eq))]
14pub struct PacketEvent {
15 pub timestamp_ns: u64,
16 pub packet_len: u32,
17 pub _padding: u32,
18}
19
20/// Network flow event with full 5-tuple and container identification
21///
22/// Layout (32 bytes total, 8-byte aligned):
23/// - timestamp_ns: Kernel timestamp in nanoseconds
24/// - cgroup_id: Container cgroup ID for pod correlation (0 for TC classifiers)
25/// - src_ip: Source IPv4 address (first octet in LSB, as read from TC classifier)
26/// - dst_ip: Destination IPv4 address (first octet in LSB, as read from TC classifier)
27/// - src_port: Source port (host byte order)
28/// - dst_port: Destination port (host byte order)
29/// - protocol: IP protocol (6=TCP, 17=UDP, 1=ICMP)
30/// - direction: Traffic direction (0=ingress, 1=egress)
31/// - packet_len: Packet size in bytes
32///
33/// Note: IP addresses are stored with first octet in LSB position. For example,
34/// 10.0.0.5 is stored as 0x0500000A. Use `from_le_bytes` when parsing IP strings.
35#[repr(C)]
36#[derive(Clone, Copy, Debug)]
37#[cfg_attr(feature = "userspace", derive(PartialEq, Eq))]
38pub struct NetworkFlowEvent {
39 pub timestamp_ns: u64,
40 pub cgroup_id: u64,
41 pub src_ip: u32,
42 pub dst_ip: u32,
43 pub src_port: u16,
44 pub dst_port: u16,
45 pub protocol: u8,
46 pub direction: u8,
47 pub packet_len: u16,
48}
49
50/// Traffic direction constants
51pub mod direction {
52 pub const INGRESS: u8 = 0;
53 pub const EGRESS: u8 = 1;
54}
55
56/// IP protocol constants
57pub mod protocol {
58 pub const ICMP: u8 = 1;
59 pub const TCP: u8 = 6;
60 pub const UDP: u8 = 17;
61}
62
63#[cfg(feature = "userspace")]
64const _: () = {
65 assert!(
66 core::mem::size_of::<PacketEvent>() == 16,
67 "PacketEvent must be exactly 16 bytes"
68 );
69 assert!(
70 core::mem::align_of::<PacketEvent>() == 8,
71 "PacketEvent must be 8-byte aligned"
72 );
73};
74
75#[cfg(feature = "userspace")]
76const _: () = {
77 assert!(
78 core::mem::size_of::<NetworkFlowEvent>() == 32,
79 "NetworkFlowEvent must be exactly 32 bytes"
80 );
81 assert!(
82 core::mem::align_of::<NetworkFlowEvent>() == 8,
83 "NetworkFlowEvent must be 8-byte aligned"
84 );
85};