{"id":51874417,"url":"https://github.com/skaiui2/ccbpf","last_synced_at":"2026-07-25T05:01:50.016Z","repository":{"id":331218504,"uuid":"1125754430","full_name":"skaiui2/ccbpf","owner":"skaiui2","description":"A lightweight compiler and virtual machine that implements eBPF-like embedded programming language, with a unique capability of execution migration.","archived":false,"fork":false,"pushed_at":"2026-06-27T12:03:47.000Z","size":347,"stargazers_count":49,"open_issues_count":2,"forks_count":10,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-27T13:13:47.541Z","etag":null,"topics":["bpf","bpfilter","c","cbpf","compiler","debugger","ebpf","embedded","hooks","language","linux","mcu","migrated","mock","perfomance","testing-tools","vm"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skaiui2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-31T09:46:30.000Z","updated_at":"2026-06-27T12:03:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/skaiui2/ccbpf","commit_stats":null,"previous_names":["skaiui2/ccbpf"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/skaiui2/ccbpf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skaiui2%2Fccbpf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skaiui2%2Fccbpf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skaiui2%2Fccbpf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skaiui2%2Fccbpf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skaiui2","download_url":"https://codeload.github.com/skaiui2/ccbpf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skaiui2%2Fccbpf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35866688,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-25T02:00:06.922Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bpf","bpfilter","c","cbpf","compiler","debugger","ebpf","embedded","hooks","language","linux","mcu","migrated","mock","perfomance","testing-tools","vm"],"created_at":"2026-07-25T05:01:49.214Z","updated_at":"2026-07-25T05:01:49.996Z","avatar_url":"https://github.com/skaiui2.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ccbpf — A tiny eBPF-like system for MCUs\n\n[中文介绍](docs/中文/readme中文.md)\n\nccbpf is a minimal dynamic‑programming component designed for **MCU / RTOS / bare‑metal systems**.\n It consists of a **C‑subset compiler** and a **BPF virtual machine**, inspired by Linux eBPF but smaller, simpler, and far more portable.\n\nIts core mission is simple:\n\n**Bring Linux‑style runtime code loading to MCUs — without reflashing firmware.**\n\n```mermaid\ngraph LR\n    A[\"Frontend\u003cbr/\u003e\u003csub\u003eLexer · Parser · AST\u003c/sub\u003e\"] \n        --\u003e B[\"IR\u003cbr/\u003e\u003csub\u003eThree‑Address Code\u003c/sub\u003e\"]\n        --\u003e C[\"Backend\u003cbr/\u003e\u003csub\u003eLowering to Classic BPF\u003c/sub\u003e\"]\n        --\u003e D[\".ccbpf Image\u003cbr/\u003e\u003csub\u003eBPF · Strings · Maps\u003c/sub\u003e\"]\n        --\u003e E[\"BPF VM\u003cbr/\u003e\u003csub\u003e Native  Hooks\u003c/sub\u003e\"]\n\n```\n\n\n\n# Why ccbpf?\n\nTraditional MCU firmware is static:\n update = recompile + flash + reboot.\n\nccbpf provides a **simple, verifiable, extremely lightweight** runtime‑loadable mechanism for:\n\n- Inserting hooks into **RTOS kernels**\n- Filtering, monitoring, and modifying data in **protocol stacks**\n- Extending behavior in **file systems / drivers**\n- Distributing logic across nodes (e.g., the lttit project)\n\nIn short:\n **No reboot. No rebuild. No reflashing.**\n\n# ccbpf vs. Linux eBPF\n\n| Feature      | Linux eBPF      | ccbpf                      |\n| ------------ | --------------- | -------------------------- |\n| Runtime      | Linux kernel    | MCU / RTOS / bare‑metal    |\n| Complexity   | High            | Minimal                    |\n| Toolchain    | LLVM/Clang      | Built‑in C subset compiler |\n| Safety       | Verifier        | Language + VM limits       |\n| Program Type | Many            | Hook programs              |\n| Footprint    | MB‑level        | KB‑level                   |\n| Portability  | Linux‑dependent | Fully platform‑agnostic    |\n\n**eBPF makes Linux programmable;\n ccbpf brings the same idea to MCUs.**\n\n# Design Highlights\n\nccbpf is not a port of eBPF — it is a ground‑up minimal design for MCUs:\n\n- Restricted C subset (no loops, no pointer arithmetic)\n- Tiny BPF VM (a few KB)\n- Loadable program format\n- Pluggable hook mechanism\n- Simple map interface\n- Fully platform‑independent (Linux / RTOS / bare‑metal)\n\nDesign goals:\n\n- **Simple implementation**\n- **Predictable behavior**\n- **Easy verification**\n- **Tiny footprint**\n- **Embedded‑friendly**\n\n# Memory Usage\n\n- Compiling ~15 C statements on a 20KB‑RAM MCU: **~8KB**\n- Compiling ~100 statements → 397 BPF instructions: **\u003c60KB peak**\n- VM running \u003c200 instructions: **1–2KB RAM**\n\n\n\n# Quick Run Demo\n\n```bash\ngit clone https://github.com/skaiui2/ccbpf.git\ncd ccbpf\nchmod +x *.sh\n```\n\n## Dynamic Program Injection Demo\n\nOpen two terminals: one runs nodeA, the other runs nodeB.\n\nRun nodeA:\n\n```bash\n./run_nodeA.sh\n```\n\nYou will then see some output information.\n\nThis indicates that the nodeA program is running, and it is counting each UDP packet.\n\n```\nskaiuijing@skaiuijing-virtual-machine:~/Documents/ccbpf_git/ccbpf/nodeB/build$ ./run_nodeA.sh\n[sudo] password for skaiuijing: \n[wirefisher] pps=1, bps=208\n[wirefisher] pps=36, bps=7488\n[wirefisher] pps=37, bps=7696\n[wirefisher] pps=36, bps=7488\n[wirefisher] pps=36, bps=7488\n[wirefisher] pps=40, bps=8320\n[wirefisher] pps=39, bps=8112\n[wirefisher] pps=37, bps=7696\n```\n\nThe demo program we inject implements a token-bucket rate limiting algorithm. Run:\n\n```bash\n./attach.sh\n```\n\nYou will then see a series of compiler outputs, and you will observe that the output of nodeA changes immediately:\n\n```\n[wirefisher] pps=37, bps=7696\n[wirefisher] pps=40, bps=8320\n[hook] ATTACH hook_udp_input (prog=0x607398e83968)\nnow_time=32082220\ntokens=0\nlast_ts=0\ntokens2=3000\n[PASS] sport=10000 dport=20000 len=208 tokens=2792\nnow_time=32082229\ntokens=2792\nlast_ts=32082220\nadd=45\ntokens2=2837\n```\n\nThe count statistics will continuously update, while UDP packet source and destination ports are parsed.\n\nSince the generated packets use fixed source and destination ports (with different sizes), only the counters will change.\n\n### Unload Program\n\nUse the following command to detach the BPF program:\n\n```bash\n./detach.sh\n```\n\nWe will observe that the output of nodeA returns to normal:\n\n```\nlast_ts=32096900\nadd=80\ntokens2=976\n[DROP] sport=10000 dport=20000 len=208\n[hook] DETACH hook_udp_input\n[wirefisher] pps=37, bps=7696\n[wirefisher] pps=34, bps=7072\n[wirefisher] pps=34, bps=7072\n[wirefisher] pps=34, bps=7072\n[wirefisher] pps=35, bps=7280\n[wirefisher] pps=35, bps=7280\n[wirefisher] pps=35, bps=7280\n[wirefisher] pps=38, bps=7904\n[wirefisher] pps=38, bps=7904\n```\n\n## Execution Migration Demo\n\nIn this demo, the program executes several steps on nodeD first, and then migrates to nodeC to continue execution.\n\nStart the process:\n\n```bash\n./run_nodeD.sh\n```\n\nThen in another terminal, run nodeC:\n\n```bash\n./run_nodeC.sh\n```\n\nYou will see that after nodeC starts, the output is:\n\n```\nnodeC: running....\nnodeC: 1\nnodeC: 2\nnodeC: 3\nnodeC: 4\nnodeC: 5\nnodeC: migration_start\nnodeC: migrate PC is 87\n```\n\nThen nodeD continues printing:\n\n```\nnodeC: migration_end\nnodeC: 6\nnodeC: 7\nnodeC: 8\nnodeC: 9\nnodeC: 10\nnodeC: 11\nnodeC: ok!!!\nnodeD: finished 0\n```\n\nThis demonstrates execution migration: the virtual machine is suspended, packaged, and then resumed on nodeD to continue execution.\n\n# Documentation\n\nDesign document: [design](docs/English/design.md)\nUsage reference: [usage](docs/English/usage.md)\n\n设计: [设计文档](docs/中文/设计文档.md)\n使用: [使用文档](docs/中文/使用文档.md)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskaiui2%2Fccbpf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskaiui2%2Fccbpf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskaiui2%2Fccbpf/lists"}