{"id":29571211,"url":"https://github.com/o-x-l/ebpf-getting-started-guide","last_synced_at":"2026-05-18T05:45:28.928Z","repository":{"id":305219662,"uuid":"1022202380","full_name":"O-X-L/ebpf-getting-started-guide","owner":"O-X-L","description":"A guide that sums up some information about eBPF for beginners","archived":false,"fork":false,"pushed_at":"2025-07-26T12:31:46.000Z","size":26,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-26T18:22:57.125Z","etag":null,"topics":["bpf","ebpf","getting-started","network-analysis","network-intelligence","tutorial"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/O-X-L.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}},"created_at":"2025-07-18T16:18:57.000Z","updated_at":"2025-07-26T12:31:50.000Z","dependencies_parsed_at":"2025-07-19T00:30:22.779Z","dependency_job_id":null,"html_url":"https://github.com/O-X-L/ebpf-getting-started-guide","commit_stats":null,"previous_names":["o-x-l/ebpf-getting-started-guide"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/O-X-L/ebpf-getting-started-guide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Febpf-getting-started-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Febpf-getting-started-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Febpf-getting-started-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Febpf-getting-started-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/O-X-L","download_url":"https://codeload.github.com/O-X-L/ebpf-getting-started-guide/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Febpf-getting-started-guide/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275221642,"owners_count":25426318,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-15T02:00:09.272Z","response_time":75,"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","ebpf","getting-started","network-analysis","network-intelligence","tutorial"],"created_at":"2025-07-19T04:00:50.210Z","updated_at":"2026-05-18T05:45:28.886Z","avatar_url":"https://github.com/O-X-L.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# eBPF Getting-Started Guide\n\n**WARNING: This guide is still work-in-progress.**\n\nWe had some problems finding simple eBPF examples that worked out-of-the box and provided containerized build-environments.\n\nThis getting-started guide should help new eBPF-users to get started more quickly.\n\nIf you have ideas on how to extend or improve this guide =\u003e [open an issue](https://github.com/O-X-L/ebpf-getting-started-guide/issues) or [email us](mailto://contact+ebpf@oxl.at)\n\n----\n\n## Use Cases\n\nBPF can be used for many use cases.\n\nIf you are new to it, you should look into the [program types](https://docs.ebpf.io/linux/program-type/) to get an idea of what you can use it for.\n\nThey differ in the way they are called (*some have hooks*), the return values that are expected and thus the functionality the modules of this type can provide.\n\nExamples:\n* [BPF_PROG_TYPE_XDP](https://docs.ebpf.io/linux/program-type/BPF_PROG_TYPE_XDP/) =\u003e can process network traffic very early on and thus can be used for defending against (D)DOS as described in [this Cloudflare blog](https://blog.cloudflare.com/cloudflare-architecture-and-how-bpf-eats-the-world/)\n* [BPF_PROG_TYPE_SOCKET_FILTER](https://docs.ebpf.io/linux/program-type/BPF_PROG_TYPE_SOCKET_FILTER/) =\u003e can be used to extend IPTables/NFTables rulesets as described in [this Cloudflare blog](https://blog.cloudflare.com/programmable-packet-filtering-with-magic-firewall/)\n* [BPF_PROG_TYPE_LWT_IN](https://docs.ebpf.io/linux/program-type/BPF_PROG_TYPE_LWT_IN/) =\u003e apply route-based filters\n* [BPF_PROG_TYPE_LSM](https://docs.ebpf.io/linux/program-type/BPF_PROG_TYPE_LSM/) =\u003e can implement security-filters for specific system-events\n\n----\n\n## Concepts\n\nSee also: [eBPF Docs - Concepts](https://docs.ebpf.io/linux/concepts/)\n\n### Pinning\n\nAs we've looked into the integration of eBPF modules for NFTables/IPTables - we've seen pinned-objects being mentioned.\n\nBPF can have a filesystem (`/sys/fs/bpf`) that contains references to currently loaded BPF objects.\n\nhttps://docs.ebpf.io/linux/concepts/pinning/\n\n### Concurrency / Race Conditions\n\nYou have to be aware of [possible race conditions](https://docs.ebpf.io/linux/concepts/concurrency/) when writing data to shared objects like maps!\n\nThe docs mention some options to work around such issues.\n\n----\n\n## Building: Raw vs eBPF-go\n\nWe would recommend using a containerized build-environment. For the examples in this repository your will have to have [Docker installed](https://docs.docker.com/engine/install/).\n\nHere we will cover two ways in which you can use eBPF:\n\n----\n\n### Raw\n\nCompile the module directly.\n\nTo run: `make build_raw` or `bash scripts/build_raw.sh`\n\nLook into the script and `docker/Dockerfile_build_raw` to get to know how it is done.\n\nUsage examples:\n\n* [Traffic control](https://man7.org/linux/man-pages/man8/tc-bpf.8.html):\n\n    ```bash\n    # Load the clsact qdisc on the interface (if not already loaded)\n    tc qdisc add dev eth0 clsact\n\n    # Add a BPF program as a classifier (filter) on ingress\n    tc filter add dev eth0 ingress bpf da obj bpf_prog.o sec classifier\n    \n    # Add a BPF program as an action on egress\n    tc filter add dev eth0 egress bpf da obj bpf_prog.o sec action\n    ```\n\n----\n\n### eBPF-go\n\nLoad module in go user-space process and get push information from eBPF to go to process it.\n\nFor more examples see: [cilium/ebpf/blob/main/examples](https://github.com/cilium/ebpf/blob/main/examples)\n\n\nTo run: `make build_go` or `bash scripts/build_go_single.sh \u003crelative-src-path\u003e`\n\nLook into the script and `docker/Dockerfile_build_go` to get to know how it is done.\n\n----\n\n## Debug Output (Print)\n\nYou can use `bpf_trace_printk(fmt, sizeof(fmt));` to temporarily enable debug-output. See: [eBPF Docs](https://docs.ebpf.io/linux/helper-function/bpf_trace_printk/)\n\nYou can read it via: `sudo cat /sys/kernel/tracing/trace | grep BPF` (if you add prefix like `[eBPF]` to the message)\n\nNOTE: `bpf_trace_printk` can only take 3 format-parameters.\n\n**Examples:**\n\n* Format IPv4\n\n  ```c\n  const char log_ip4[] = \"[eBPF] IP4: %pI4\\n\";\n  bpf_trace_printk(log_ip4, sizeof(log_ip4), \u0026ip4-\u003esaddr);\n  // bpf_trace_printk: [eBPF] IP4: 127.0.0.1\n  ```\n\n* Format IPv6\n\n  ```c\n  const char log_ip6[] = \"[eBPF] IP6: %pI6\\n\";\n  bpf_trace_printk(log_ip6, sizeof(log_ip6), \u0026ip6-\u003esaddr);\n  // bpf_trace_printk: [eBPF] IP6: fe80:0000:0000:0000:c87f:acff:fe69:287a\n  ```\n\n* Write hex of int\n\n  ```c\n  const char log_ip6_p1[] = \"[eBPF] IP6: Parts 1+2 (0x%x 0x%x)\\n\";\n  bpf_trace_printk(log_ip6_p1, sizeof(log_ip6_p1), bpf_ntohl(ip6o.addr[0]), bpf_ntohl(ip6o.addr[1]));\n  const char log_ip6_p2[] = \"[eBPF] IP6: Parts 3+4 (0x%x 0x%x)\\n\";\n  bpf_trace_printk(log_ip6_p2, sizeof(log_ip6_p2), bpf_ntohl(ip6o.addr[2]), bpf_ntohl(ip6o.addr[3]));\n  // bpf_trace_printk: [eBPF] IP6: Parts 1+2 (0xfe800000 0x0)\n  // bpf_trace_printk: [eBPF] IP6: Parts 3+4 (0xc87facff 0xfe69287a)\n  ```\n\n----\n\n## IPv6\n\nWe've found that you can run into issues with IPv6 addresses as they have 128-bit vs the 32-bit of IPv4.\n\nIf you want to pass it to your user-space process you might need/want to split it into 32-bit chunks:\n\n```c\nstruct ip6_addr {\n    __u32 addr[4];\n};\n\nstatic __always_inline void process_ip6(struct ethhdr *ethhdr) {\n    struct ipv6hdr *ip6h = (void *)(ethhdr + 1);\n\n    // create and populate\n    struct ip6_addr ip6_src;\n    __builtin_memcpy(\u0026ip6_src.addr, \u0026ip6h-\u003esaddr, sizeof(ip6_src.addr));\n\n    // convert network to host\n    ip6_src.addr[0] = bpf_ntohl(ip6_src.addr[0]);\n    ip6_src.addr[1] = bpf_ntohl(ip6_src.addr[1]);\n    ip6_src.addr[2] = bpf_ntohl(ip6_src.addr[2]);\n    ip6_src.addr[3] = bpf_ntohl(ip6_src.addr[3]);\n\n    // debug log\n    const char log_ip6_p1[] = \"[eBPF] IP6: Parts 1+2 (0x%x 0x%x)\\n\";\n    bpf_trace_printk(log_ip6_p1, sizeof(log_ip6_p1), ip6o.addr[0], ip6o.addr[1]);\n    const char log_ip6_p2[] = \"[eBPF] IP6: Parts 3+4 (0x%x 0x%x)\\n\";\n    bpf_trace_printk(log_ip6_p2, sizeof(log_ip6_p2), ip6o.addr[2], ip6o.addr[3]);\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-x-l%2Febpf-getting-started-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fo-x-l%2Febpf-getting-started-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-x-l%2Febpf-getting-started-guide/lists"}