К основному содержанию
скилл CX Codex

ebpf-rust — скилл для Claude Code: что делает и как установить

Руководство по разработке eBPF-программ на Rust с фреймворком Aya. Помогает писать код ядра, передавать события через Tokio и разбирать ошибки верификатора.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add mohitmishra786/low-level-dev-skills --skill ebpf-rust -a claude-code
Открыть на GitHub

Что делает ebpf-rust

Скилл настраивает работу с фреймворком Aya для создания eBPF-программ на чистом Rust. Он описывает структуру workspace из двух крейтов: ядра на базе aya-bpf без стандартной библиотеки (#![no_std]) и сервиса пространства пользователя. В инструкции собраны примеры макросов для хуков #[tracepoint], #[kprobe], #[xdp] и сетевого фильтра #[tc] вместе со структурированным логированием через aya-log.

Внутри описан обмен данными через структуры HashMap, RingBuf и LruHashMap. Для асинхронного чтения событий из буфера в userspace используется интеграция RingBuf с tokio::io::unix::AsyncFd. Также скилл показывает, как генерировать привязки к BTF ядра через aya-tool и читать поля структур через макрос bpf_core_read!.

Для загрузки программ в ядро требуются права суперпользователя или привилегии CAP_BPF и CAP_SYS_ADMIN. Без них ядро вернёт ошибку доступа. При сбоях верификатора запускайте сборку с переменной RUST_LOG=debug и проверяйте состояние через утилиту bpftool.

Какие задачи решает

  • развернуть структуру проекта eBPF на Rust с помощью шаблона Aya
  • написать ядерную программу под tracepoint или kprobe без libc
  • организовать передачу событий из ядра в Tokio через RingBuf
  • устранить ошибки верификатора BPF при загрузке программы в ядро

Примеры запросов агенту

  • Как написать трейспоинт на Rust с помощью aya-bpf?
  • Покажи пример чтения событий из BPF RingBuf в приложении на tokio.
  • Моя программа на Aya не проходит верификатор BPF, как её отладить?

Как установить ebpf-rust

1Через Skills CLI (Vercel)

npx skills add mohitmishra786/low-level-dev-skills --skill ebpf-rust -a claude-code

2Вручную: положить файлы

~/.claude/skills/ebpf-rust/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/ebpf-rust/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о ebpf-rust

Как установить ebpf-rust в Claude Code?

Выполните в терминале команду npx skills add mohitmishra786/low-level-dev-skills --skill ebpf-rust -a claude-code. Она запишет файл по пути ~/.claude/skills/ebpf-rust/SKILL.md.

Что делает скилл ebpf-rust?

Он предоставляет готовые шаблоны и правила для разработки eBPF-модулей ядра на Rust, настройки общих карт памяти и интеграции с асинхронным рантаймом Tokio.

Какие системные права нужны для работы скомпилированной программы?

Для загрузки BPF-байткода и создания карт требуются привилегии CAP_BPF или CAP_SYS_ADMIN, поэтому исполняемый файл запускается через sudo.

Исходный текст

SKILL.md · MIT
---
name: ebpf-rust
description: Rust eBPF skill using the Aya framework. Use when writing eBPF programs in Rust with aya-bpf and aya-log, defining BPF map types, integrating with tokio userspace, sharing maps between kernel and userspace, or debugging Aya compilation and loading errors. Activates on queries about Aya, aya-bpf, Rust eBPF, aya-log, eBPF in Rust, or BPF programs with tokio.
---

# eBPF with Rust (Aya)

## Purpose

Guide agents through building production eBPF programs in Rust using the Aya framework: writing kernel-side BPF code with `aya-bpf`, structured logging with `aya-log`, sharing maps between BPF and userspace, and integrating with async tokio.

## Triggers

- "How do I write an eBPF program in Rust?"
- "How do I use the Aya framework?"
- "How do I share a BPF map between kernel and userspace in Rust?"
- "How do I log from a BPF program in Rust?"
- "My Aya program fails to load — how do I debug it?"
- "How do I integrate an eBPF program with tokio?"

## Workflow

### 1. Project setup

```bash
# Install aya-tool (generates bindings from vmlinux BTF)
cargo install aya-tool

# Create new Aya project from template
cargo install cargo-generate
cargo generate https://github.com/aya-rs/aya-template

# Workspace layout (generated)
# my-ebpf/
# ├── my-ebpf-ebpf/    <- kernel-side crate (target: bpf)
# ├── my-ebpf/         <- userspace crate (runs on host)
# └── xtask/           <- build helper (cargo xtask build/run)
```

```bash
# Build both sides
cargo xtask build-ebpf          # builds BPF object
cargo xtask run                 # builds + runs with sudo
```

### 2. Kernel-side BPF program

```rust
// my-ebpf-ebpf/src/main.rs
#![no_std]
#![no_main]

use aya_bpf::{
    macros::{map, tracepoint},
    maps::HashMap,
    programs::TracePointContext,
    helpers::bpf_get_current_pid_tgid,
};
use aya_log_ebpf::info;

#[map]
static CALL_COUNT: HashMap<u32, u64> = HashMap::with_max_entries(1024, 0);

#[tracepoint]
pub fn trace_read(ctx: TracePointContext) -> u32 {
    let pid = (bpf_get_current_pid_tgid() >> 32) as u32;

    // Lookup or insert
    match unsafe { CALL_COUNT.get(&pid) } {
        Some(count) => {
            let _ = CALL_COUNT.insert(&pid, &(count + 1), 0);
        }
        None => {
            let _ = CALL_COUNT.insert(&pid, &1u64, 0);
        }
    }

    info!(&ctx, "read() called by pid {}", pid);
    0
}

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
    unsafe { core::hint::unreachable_unchecked() }
}
```

### 3. Userspace loader with tokio

```rust
// my-ebpf/src/main.rs
use aya::{Bpf, programs::TracePoint, maps::HashMap};
use aya_log::BpfLogger;
use tokio::signal;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Load compiled BPF object (embedded at build time)
    let mut bpf = Bpf::load(include_bytes_aligned!(
        "../../target/bpf/my-ebpf-ebpf.bpf.o"
    ))?;

    // Initialize structured logging from BPF programs
    BpfLogger::init(&mut bpf)?;

    // Attach tracepoint
    let program: &mut TracePoint = bpf.program_mut("trace_read").unwrap().try_into()?;
    program.load()?;
    program.attach("syscalls", "sys_enter_read")?;

    // Read from shared map
    let map: HashMap<_, u32, u64> = HashMap::try_from(bpf.map("CALL_COUNT").unwrap())?;

    // Wait for Ctrl+C
    signal::ctrl_c().await?;

    // Print final counts
    for (pid, count) in map.iter().filter_map(|r| r.ok()) {
        println!("PID {}: {} reads", pid, count);
    }
    Ok(())
}
```

### 4. Map types in Aya

```rust
use aya_bpf::maps::{HashMap, Array, RingBuf, PerfEventArray, LruHashMap};

// Hash map
#[map]
static MY_MAP: HashMap<u32, u64> = HashMap::with_max_entries(1024, 0);

// Ring buffer (preferred for events)
#[map]
static EVENTS: RingBuf = RingBuf::with_byte_size(256 * 1024, 0);

// LRU hash (connection tracking)
#[map]
static CONNS: LruHashMap<u32, ConnInfo> = LruHashMap::with_max_entries(10000, 0);

// Sending events via RingBuf (kernel side)
if let Ok(mut entry) = unsafe { EVENTS.reserve::<MyEvent>(0) } {
    entry.write(MyEvent { pid, ts });
    entry.submit(0);
}
```

```rust
// Reading RingBuf events (userspace)
use aya::maps::RingBuf;
use tokio::io::unix::AsyncFd;

let ring = RingBuf::try_from(bpf.take_map("EVENTS").unwrap())?;
let mut ring = AsyncFd::new(ring)?;

loop {
    let mut guard = ring.readable_mut().await?;
    let rb = guard.get_inner_mut();
    while let Some(item) = rb.next() {
        let event: &MyEvent = unsafe { &*(item.as_ptr() as *const MyEvent) };
        println!("Event from PID {}", event.pid);
    }
    guard.clear_ready();
}
```

### 5. Supported program types

| Aya macro | Program type | Attach target |
|-----------|-------------|---------------|
| `#[tracepoint]` | Tracepoint | `"syscalls", "sys_enter_read"` |
| `#[kprobe]` | kprobe | function name |
| `#[kretprobe]` | kretprobe | function name |
| `#[uprobe]` | uprobe | userspace binary + offset |
| `#[xdp]` | XDP | network interface |
| `#[tc]` | TC (traffic control) | netdevice + direction |
| `#[socket_filter]` | Socket filter | raw socket fd |
| `#[perf_event]` | Perf event | perf_event fd |
| `#[lsm]` | LSM hook | security hook name |
| `#[sk_msg]` | Sockmap | socket map |

### 6. Generating kernel type bindings

```bash
# Generate bindings from running kernel's BTF
aya-tool generate task_struct > src/vmlinux.rs

# Or use btf_type_tag and CO-RE
# aya-bpf supports CO-RE via bpf_core_read! macro
```

```rust
// CO-RE field access in Aya
use aya_bpf::helpers::bpf_core_read;

let dport: u16 = unsafe {
    bpf_core_read!(sk, __sk_common.skc_dport)?
};
```

### 7. Debugging load failures

```bash
# Check verifier errors (Aya surfaces them as Rust errors)
# Run with RUST_LOG=debug for verbose output
RUST_LOG=debug cargo xtask run 2>&1 | grep -A 20 "verifier"

# Check BTF info
bpftool btf dump file /sys/kernel/btf/vmlinux | grep task_struct

# Inspect loaded programs after load
bpftool prog list
bpftool prog dump xlated name trace_read
```

| Error | Cause | Fix |
|-------|-------|-----|
| `invalid mem access` | Unbounded pointer dereference | Add null check before reading |
| `Type not found` | BTF mismatch with kernel | Regenerate vmlinux bindings |
| `Permission denied` | No CAP_BPF or CAP_SYS_ADMIN | Run with `sudo` or set capability |
| `map already exists` | Map pinned, name collision | Unpin or rename map |

## Related skills

- Use `skills/observability/ebpf` for C-based eBPF with libbpf
- Use `skills/rust/rust-async-internals` for tokio async patterns used in userspace
- Use `skills/rust/rust-unsafe` for unsafe code patterns in BPF helpers

© mohitmishra786 · MIT · mohitmishra786/low-level-dev-skills

Похожие скиллы

Все скиллы по теме «Языки программирования» →
migrate-to-shoehorn Matt Pocock Переводит type assertions с as в тестах на функции из @total-typescript/shoehorn. Нужен для частичных объектов и намеренно неверных данных в проверках. 475 388установок write-swift emilkowalski Скилл помогает писать, проверять и переносить код на Swift с учётом модели языка. Подойдёт, когда нужно разобраться с конкурентностью, ошибкой или циклом удержания объектов. CX Codex +1 119 300установок megacave JuliusBrussee Переводит ответы ассистента на классический китайский язык (вэньянь) для экономии места на экране. Активируется командами /megacave или /caveman wenyan. CX Codex +1 25 400установок find-docs upstash Тянет актуальную документацию, справочники API и примеры кода для любой библиотеки через Context7 CLI. Пригодится, когда агент отвечает по устаревшим данным обучения. CX Codex +1 9 400установок typescript-advanced-types Seth Hobson Помогает агенту писать сложную типизацию TypeScript: generics, conditional types и преобразования типов. Нужен для библиотек, API-клиентов и строгих конфигураций. CX Codex 92 169установок smart-explore thedotmack Структурно ищет функции и классы через tree-sitter. Пригодится, когда нужно разобраться в кодовой базе без чтения всех файлов. CX Codex +1 7 300установок

Из того же набора90

rust-async-internals Помогает агенту объяснять и отлаживать async Rust: модель poll, Pin и Unpin, планировщик tokio, утечки waker. Пригодится, когда задача виснет или тормозит. CX Codex +1 467установок zig-compiler Ведёт агента по вызову компилятора Zig: режимы оптимизации, типы сборки, zig cc вместо C-компилятора и разбор сообщений об ошибках. CX Codex +1 450установок zig-comptime Скилл для агентов, который помогает писать обобщённые функции, рефлексию типов и код, вычисляемый на этапе компиляции в Zig. CX Codex +1 443установок zig-testing Скилл ведёт агента по тестовой системе Zig: zig build test, фильтры, comptime-проверки, тестовый аллокатор и встроенный фаззер. CX Codex +1 440установок bazel Ведёт агента по Bazel в C/C++ проектах: BUILD-файлы, правила cc_library и cc_binary, тулчейны, запросы к графу зависимостей. CX Codex +1 437установок stm32-baremetal Ведёт агента по сборке прошивки STM32 на одних заголовках CMSIS: тактовые частоты, RCC, линкерный скрипт, сборка через arm-none-eabi-gcc. CX Codex +1 360установок device-drivers Скилл ведёт агента по разработке драйверов ядра Linux: platform/i2c/spi, символьные устройства, IRQ, DMA, regmap и runtime PM. CX Codex +1 358установок reverse-engineering Скилл для разбора скомпилированных бинарей: подсказывает агенту порядок работы с Ghidra, radare2 и Binary Ninja. Пригодится, когда исходников нет, а логику восстановить надо. CX Codex +1 350установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой