diff --git a/os/StarryOS/kernel/src/ebpf.rs b/os/StarryOS/kernel/src/ebpf.rs
new file mode 100644
index 0000000000..944e8e892c
--- /dev/null
+++ b/os/StarryOS/kernel/src/ebpf.rs
@@ -0,0 +1,2429 @@
+//! eBPF (Extended Berkeley Packet Filter) subsystem for StarryOS.
+//!
+//! This module provides a complete in-kernel eBPF implementation including:
+//!
+//! - **Map management**: Array and Hash maps with fd-based lifecycle
+//! - **Program loader**: Parses `bpf_attr` with correct mixed u32/u64 byte-offset layout
+//! - **Instruction interpreter**: Supports ALU/JMP/MEM instruction classes with
+//! BPF_EXIT and BPF_CALL handling
+//! - **Helper functions**: 11 helpers including map operations, probe_read, ktime,
+//! PID/TGID, UID/GID, and perf_event_output
+//! - **fd table**: BpfFdTable with close/remove operations and free-fd reuse
+//!
+//! # Syscall interface
+//!
+//! Implements `bpf()` syscall commands: MAP_CREATE, LOOKUP, UPDATE, DELETE,
+//! GET_NEXT_KEY, PROG_LOAD, PROG_ATTACH, LINK_CREATE, OBJ_CLOSE.
+
+use alloc::vec::Vec;
+
+use ax_errno::{AxError, AxResult};
+use ax_sync::spin::SpinNoIrq;
+
+use crate::task::AsThread;
+
+mod ebpf_jit;
+
+#[allow(dead_code)]
+mod bpf_insn {
+ pub const BPF_LD: u8 = 0x00;
+ pub const BPF_LDX: u8 = 0x01;
+ pub const BPF_ST: u8 = 0x02;
+ pub const BPF_STX: u8 = 0x03;
+ pub const BPF_ALU: u8 = 0x04;
+ pub const BPF_JMP: u8 = 0x05;
+ pub const BPF_JMP32: u8 = 0x06;
+ pub const BPF_ALU64: u8 = 0x07;
+
+ pub const BPF_W: u8 = 0x00;
+ pub const BPF_H: u8 = 0x08;
+ pub const BPF_B: u8 = 0x10;
+ pub const BPF_DW: u8 = 0x18;
+
+ pub const BPF_IMM: u8 = 0x00;
+ pub const BPF_ABS: u8 = 0x20;
+ pub const BPF_IND: u8 = 0x40;
+ pub const BPF_MEM: u8 = 0x60;
+ pub const BPF_LEN: u8 = 0x80;
+ pub const BPF_MSH: u8 = 0xa0;
+
+ pub const BPF_ADD: u8 = 0x00;
+ pub const BPF_SUB: u8 = 0x10;
+ pub const BPF_MUL: u8 = 0x20;
+ pub const BPF_DIV: u8 = 0x30;
+ pub const BPF_OR: u8 = 0x40;
+ pub const BPF_AND: u8 = 0x50;
+ pub const BPF_LSH: u8 = 0x60;
+ pub const BPF_RSH: u8 = 0x70;
+ pub const BPF_NEG: u8 = 0x80;
+ pub const BPF_MOD: u8 = 0x90;
+ pub const BPF_XOR: u8 = 0xa0;
+ pub const BPF_MOV: u8 = 0xb0;
+ pub const BPF_ARSH: u8 = 0xc0;
+ pub const BPF_END: u8 = 0xd0;
+
+ pub const BPF_JA: u8 = 0x00;
+ pub const BPF_EXIT: u8 = 0x90;
+ pub const BPF_JEQ: u8 = 0x10;
+ pub const BPF_JGT: u8 = 0x20;
+ pub const BPF_JGE: u8 = 0x30;
+ pub const BPF_JSET: u8 = 0x40;
+ pub const BPF_JNE: u8 = 0x50;
+ pub const BPF_JSGT: u8 = 0x60;
+ pub const BPF_JSGE: u8 = 0x70;
+ pub const BPF_JLT: u8 = 0xa0;
+ pub const BPF_JLE: u8 = 0xb0;
+ pub const BPF_JSLT: u8 = 0xc0;
+ pub const BPF_JSLE: u8 = 0xd0;
+
+ pub const BPF_K: u8 = 0x00;
+ pub const BPF_X: u8 = 0x08;
+
+ pub const BPF_PSEUDO_MAP_FD: u8 = 1;
+ pub const BPF_PSEUDO_MAP_VALUE: u8 = 2;
+
+ #[repr(C)]
+ #[derive(Clone, Copy, Debug, Default)]
+ pub struct BpfInsn {
+ pub code: u8,
+ pub dst_src_reg: u8,
+ pub off: i16,
+ pub imm: i32,
+ }
+
+ impl BpfInsn {
+ pub const fn new(code: u8, dst: u8, src: u8, off: i16, imm: i32) -> Self {
+ Self {
+ code,
+ dst_src_reg: (dst & 0xf) | ((src & 0xf) << 4),
+ off,
+ imm,
+ }
+ }
+
+ pub fn dst_reg(&self) -> u8 {
+ self.dst_src_reg & 0xf
+ }
+
+ pub fn src_reg(&self) -> u8 {
+ (self.dst_src_reg >> 4) & 0xf
+ }
+
+ pub fn class(&self) -> u8 {
+ self.code & 0x07
+ }
+
+ pub fn size(&self) -> u8 {
+ self.code & 0x18
+ }
+
+ pub fn mode(&self) -> u8 {
+ self.code & 0xe0
+ }
+
+ pub fn alu_op(&self) -> u8 {
+ self.code & 0xf0
+ }
+
+ pub fn is_ld_dw_imm(&self) -> bool {
+ self.code == (BPF_LD | BPF_IMM | BPF_DW)
+ }
+
+ pub fn to_bytes(self) -> [u8; 8] {
+ let mut buf = [0u8; 8];
+ buf[0] = self.code;
+ buf[1] = self.dst_src_reg;
+ buf[2..4].copy_from_slice(&self.off.to_le_bytes());
+ buf[4..8].copy_from_slice(&self.imm.to_le_bytes());
+ buf
+ }
+
+ pub fn from_bytes(bytes: &[u8; 8]) -> Self {
+ Self {
+ code: bytes[0],
+ dst_src_reg: bytes[1],
+ off: i16::from_le_bytes([bytes[2], bytes[3]]),
+ imm: i32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]),
+ }
+ }
+ }
+}
+
+#[allow(dead_code)]
+mod map_type {
+ pub const UNSPEC: u32 = 0;
+ pub const HASH: u32 = 1;
+ pub const ARRAY: u32 = 2;
+ pub const PROG_ARRAY: u32 = 3;
+ pub const PERF_EVENT_ARRAY: u32 = 4;
+ pub const PERCPU_HASH: u32 = 5;
+ pub const PERCPU_ARRAY: u32 = 6;
+ pub const STACK_TRACE: u32 = 7;
+ pub const LRU_HASH: u32 = 9;
+ pub const LRU_PERCPU_HASH: u32 = 10;
+ pub const LPM_TRIE: u32 = 11;
+ pub const QUEUE: u32 = 22;
+ pub const STACK: u32 = 23;
+ pub const RINGBUF: u32 = 27;
+}
+
+#[allow(dead_code)]
+mod prog_type {
+ pub const UNSPEC: u32 = 0;
+ pub const SOCKET_FILTER: u32 = 1;
+ pub const KPROBE: u32 = 2;
+ pub const SCHED_CLS: u32 = 3;
+ pub const TRACEPOINT: u32 = 5;
+ pub const XDP: u32 = 6;
+ pub const PERF_EVENT: u32 = 7;
+ pub const CGROUP_SKB: u32 = 8;
+ pub const RAW_TRACEPOINT: u32 = 17;
+ pub const LSM: u32 = 29;
+ pub const SYSCALL: u32 = 31;
+}
+
+#[allow(dead_code)]
+mod cmd {
+ pub const MAP_CREATE: u64 = 0;
+ pub const MAP_LOOKUP_ELEM: u64 = 1;
+ pub const MAP_UPDATE_ELEM: u64 = 2;
+ pub const MAP_DELETE_ELEM: u64 = 3;
+ pub const MAP_GET_NEXT_KEY: u64 = 4;
+ pub const PROG_LOAD: u64 = 5;
+ pub const OBJ_PIN: u64 = 6;
+ pub const OBJ_GET: u64 = 7;
+ pub const PROG_ATTACH: u64 = 8;
+ pub const PROG_DETACH: u64 = 9;
+ pub const OBJ_CLOSE: u64 = 11;
+ pub const RAW_TRACEPOINT_OPEN: u64 = 17;
+ pub const LINK_CREATE: u64 = 28;
+ pub const ENABLE_STATS: u64 = 32;
+}
+
+#[allow(dead_code)]
+mod bpf_error {
+ use ax_errno::AxError;
+
+ pub const EPERM: AxError = AxError::PermissionDenied;
+ pub const ENOENT: AxError = AxError::NotFound;
+ pub const ENOMEM: AxError = AxError::NoMemory;
+ pub const EINVAL: AxError = AxError::InvalidInput;
+ pub const ENOSPC: AxError = AxError::StorageFull;
+
+ pub fn from_linux_errno(code: i32) -> AxError {
+ match code {
+ 1 => AxError::PermissionDenied,
+ 2 => AxError::NotFound,
+ 12 => AxError::NoMemory,
+ 22 => AxError::InvalidInput,
+ 28 => AxError::StorageFull,
+ _ => AxError::Io,
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+#[allow(dead_code)]
+struct BpfMapMeta {
+ map_type: u32,
+ key_size: u32,
+ value_size: u32,
+ max_entries: u32,
+ map_flags: u32,
+ id: u32,
+}
+
+trait BpfMapOps: Send + Sync {
+ fn meta(&self) -> &BpfMapMeta;
+ fn lookup_elem(&mut self, key: &[u8]) -> AxResult