This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
devopscritical PriorityID: cilium-ebpf-tc-tail-call-stack-budget

Cilium eBPF TC Tail-Call Stack Frame Depth Budget Standard

Enforces strict limits on eBPF Traffic Control (TC) stack allocations (<256 bytes per frame) and deterministic tail-call invocation chains (<32 hops). Prevents kernel BPF verifier rejections and tail-call JIT stack frame exhaustion that cause silent packet drops during Cilium service mesh routing.

Prohibited Anti-Pattern: Exceeding 512-Byte Verifier Stack Ceilings and Unbounded Tail-Call Chaining in TC Datapaths

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Cilium eBPF TC Tail-Call Stack Frame Depth Budget Standard - Enforces strict limits on eBPF Traffic Control (TC) stack allocations (<256 bytes per frame) and deterministic tail-call invocation chains (<32 hops). Prevents kernel BPF verifier rejections and tail-call JIT stack frame exhaustion that cause silent packet drops during Cilium service mesh routing.
globs: bpf/**/*.c, bpf/**/*.h, pkg/datapath/**/*.go, pkg/ebpf/**/*.go
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/cilium-ebpf-tc-tail-call-stack-budget"
---

# Cilium eBPF TC Tail-Call Stack Frame Depth Budget Standard

> **Severity**: CRITICAL | **Category**: devops
> **Anti-Pattern Warning**: Exceeding 512-Byte Verifier Stack Ceilings and Unbounded Tail-Call Chaining in TC Datapaths

## System Constraints
You are a Principal Datapath Systems Architect enforcing strict memory and execution boundaries in Cilium eBPF Traffic Control (TC) programs. You must reject any pattern that risks exceeding the 512-byte eBPF stack limit or violates kernel tail-call chaining limits.

## Strict Guidelines
- Engineers MUST ALWAYS restrict individual eBPF subprogram and TC entry-point stack allocations to under 256 bytes to prevent combined frame overflow during inlining against the 512-byte MAX_BPF_STACK kernel limit.
- Engineers MUST ALWAYS offload data structures larger than 128 bytes (such as IP headers, CT tuples, and routing metadata) to per-CPU scratchpad maps (BPF_MAP_TYPE_PERCPU_ARRAY) rather than stack-allocating them.
- Engineers MUST NOT chain tail calls beyond an explicit structural depth limit (maximum 32 consecutive calls as mandated by Linux kernel MAX_TAIL_CALL_CNT), ensuring invocation graphs are strictly acyclic.
- Code SHOULD zero-initialize per-CPU scratchpad entries conditionally and maintain static assertions (e.g., _Static_assert) on struct sizes bound for eBPF stack frames.
- Components NEVER execute bpf_tail_call within subprograms on kernels lacking tail-call stack unrolling optimizations, as this triggers cumulative frame stack overflows or verifier rejection.

## Bad vs Good Implementations
### Cilium TC Datapath Stack and Tail-Call Execution

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Allocates ~392 bytes on the 512-byte eBPF stack within a single frame. When inlined or combined with kernel helper frames during tail-call preparation, this triggers 'combined stack size exceeds limit of 512 bytes' verifier rejections or JIT failure.
```c
// VIOLATION: Stack allocation exceeds 256 bytes; deep stack prior to tail-call
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

struct route_context {
    __u8 l2_frame[256];
    __u8 ip_options[128];
    __u32 trace_id;
    __u32 tunnel_endpoint;
};

SEC("tc")
int cilium_tc_ingress(struct __sk_buff *skb) {
    // Allocating ~392 bytes on stack; verifier rejects if inlined or chained
    struct route_context ctx;
    __builtin_memset(&ctx, 0, sizeof(ctx));

    if (bpf_skb_load_bytes(skb, 0, ctx.l2_frame, sizeof(ctx.l2_frame)) < 0)
        return TC_ACT_SHOT;

    // Tail calling from a heavy stack frame risks kernel JIT stack budget exhaustion
    bpf_tail_call(skb, &cilium_tail_call_map, ctx.tunnel_endpoint);
    
    // Fallthrough drop
    return TC_ACT_SHOT;
}
```

#### Production Standard (Correct)
> **Standard**: Offloads large payload contexts to a BPF_MAP_TYPE_PERCPU_ARRAY scratchpad, reducing TC frame stack allocation to under 32 bytes and ensuring predictable JIT compilation across tail-call hops.
```c
// COMPLIANT: Per-CPU scratch map allocation and lightweight tail-call dispatch
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

struct route_context {
    __u8 l2_frame[256];
    __u8 ip_options[128];
    __u32 trace_id;
    __u32 tunnel_endpoint;
};

struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __type(key, __u32);
    __type(value, struct route_context);
    __uint(max_entries, 1);
} cilium_scratch_map SEC(".maps");

SEC("tc")
int cilium_tc_ingress(struct __sk_buff *skb) {
    __u32 zero = 0;
    // Allocate zero stack bytes for data buffer; fetch from per-CPU scratchpad
    struct route_context *ctx = bpf_map_lookup_elem(&cilium_scratch_map, &zero);
    if (!ctx)
        return TC_ACT_SHOT;

    if (bpf_skb_load_bytes(skb, 0, ctx->l2_frame, sizeof(ctx->l2_frame)) < 0)
        return TC_ACT_SHOT;

    __u32 next_prog = ctx->tunnel_endpoint;
    // Minimal stack usage (<32 bytes) at tail-call boundary ensures JIT safety
    bpf_tail_call(skb, &cilium_tail_call_map, next_prog);

    return TC_ACT_SHOT;
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Cilium eBPF TC Tail-Call Stack Frame Depth Budget Standard

Cilium eBPF TC Tail-Call Stack Frame Depth Budget Standard defines an industrial-grade behavioral standard for devops engineering. Enforces strict limits on eBPF Traffic Control (TC) stack allocations (<256 bytes per frame) and deterministic tail-call invocation chains (<32 hops). Prevents kernel BPF verifier rejections and tail-call JIT stack frame exhaustion that cause silent packet drops during Cilium service mesh routing. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Exceeding 512-Byte Verifier Stack Ceilings and Unbounded Tail-Call Chaining in TC Datapaths Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftExceeding 512-Byte Verifier Stack Ceilings and Unbounded Tail-Call Chaining in TC DatapathsCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS restrict individual eBPF subprogram and TC entry-point stack allocations to under 256 bytes to prevent combined frame overflow during inlining against the 512-byte MAX_BPF_STACK kernel limit.

Engineers MUST ALWAYS restrict individual eBPF subprogram and TC entry-point stack allocations to under 256 bytes to prevent combined frame overflow during inlining against the 512-byte MAX_BPF_STACK kernel limit.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST ALWAYS offload data structures larger than 128 bytes (such as IP headers, CT tuples, and routing metadata) to per-CPU scratchpad maps (BPF_MAP_TYPE_PERCPU_ARRAY) rather than stack-allocating them.

Engineers MUST ALWAYS offload data structures larger than 128 bytes (such as IP headers, CT tuples, and routing metadata) to per-CPU scratchpad maps (BPF_MAP_TYPE_PERCPU_ARRAY) rather than stack-allocating them.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST NOT chain tail calls beyond an explicit structural depth limit (maximum 32 consecutive calls as mandated by Linux kernel MAX_TAIL_CALL_CNT), ensuring invocation graphs are strictly acyclic.

Engineers MUST NOT chain tail calls beyond an explicit structural depth limit (maximum 32 consecutive calls as mandated by Linux kernel MAX_TAIL_CALL_CNT), ensuring invocation graphs are strictly acyclic.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Code SHOULD zero-initialize per-CPU scratchpad entries conditionally and maintain static assertions (e.g., _Static_assert) on struct sizes bound for eBPF stack frames.

Code SHOULD zero-initialize per-CPU scratchpad entries conditionally and maintain static assertions (e.g., _Static_assert) on struct sizes bound for eBPF stack frames.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Components NEVER execute bpf_tail_call within subprograms on kernels lacking tail-call stack unrolling optimizations, as this triggers cumulative frame stack overflows or verifier rejection.

Components NEVER execute bpf_tail_call within subprograms on kernels lacking tail-call stack unrolling optimizations, as this triggers cumulative frame stack overflows or verifier rejection.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Cilium eBPF TC Tail-Call Stack Frame Depth Budget Standard critical for AI coding assistants?

Enforces strict limits on eBPF Traffic Control (TC) stack allocations (<256 bytes per frame) and deterministic tail-call invocation chains (<32 hops). Prevents kernel BPF verifier rejections and tail-call JIT stack frame exhaustion that cause silent packet drops during Cilium service mesh routing. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Exceeding 512-Byte Verifier Stack Ceilings and Unbounded Tail-Call Chaining in TC Datapaths) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Cilium