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