Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ep:labs:05:contents:tasks:ex3 [2026/03/30 22:15]
radu.mantu
ep:labs:05:contents:tasks:ex3 [2026/03/31 02:50] (current)
radu.mantu
Line 3: Line 3:
 The [[https://​ebpf.io/​|extended Berkley Packet Filter (eBPF)]] is an under-represented technology in CS curricula that has been around since 1994 but has served multiple purposes along the years. As a //tl;dr//, what you need to know about eBPF is that it's a purely virtual [[https://​docs.kernel.org/​6.3/​bpf/​instruction-set.html|instruction set]], meaning that no hardware implements it. eBPF programs can be uploaded to the kernel, where they are JIT translated to native bytecode and become callable by other kernel components. The [[https://​ebpf.io/​|extended Berkley Packet Filter (eBPF)]] is an under-represented technology in CS curricula that has been around since 1994 but has served multiple purposes along the years. As a //tl;dr//, what you need to know about eBPF is that it's a purely virtual [[https://​docs.kernel.org/​6.3/​bpf/​instruction-set.html|instruction set]], meaning that no hardware implements it. eBPF programs can be uploaded to the kernel, where they are JIT translated to native bytecode and become callable by other kernel components.
  
-The question is: why would we go through all this trouble instead of using a [[https://​embetronicx.com/​tutorials/​linux/​device-drivers/​linux-device-driver-tutorial-part-2-first-device-driver/​|Linux Kernel Module (LKM)]]? Unlike LKMs, eBPF programs have a simpler structure and can be more easily verified by the kernel. Before being JIT translated, the kernel must ensure their safety by enforcing certain properties. For example, eBPF programs are //​guaranteed//​ to finish. How does is this property checked and enforced? By making sure that eBPF programs have //no back jumps//. As you can imagine, this makes even writing a simple ''​for''​ loop a challenge.+The question is: why would we go through all this trouble instead of using a [[https://​embetronicx.com/​tutorials/​linux/​device-drivers/​linux-device-driver-tutorial-part-2-first-device-driver/​|Linux Kernel Module (LKM)]]? Unlike LKMs, eBPF programs have a simpler structure and can be more easily verified by the kernel. Before being JIT translated, the kernel must ensure their safety by enforcing certain properties. For example, eBPF programs are //​guaranteed//​ to finish. How is this property checked and enforced? By making sure that eBPF programs have //no back jumps//. As you can imagine, this makes even writing a simple ''​for''​ loop a challenge.
  
-Initially, BPF (the **extended** part was added when x64 architectures appeared ca. 2004) was used as a filtering criteria for network ​capture packets, limiting the amount of data copied to a userspace process for analysis. This is still used to this day. Try running **tcpdump <​expression>​** and adding the **-d** flag. Instead of actually listening for packets, this will dump the BPF program that **tcpdump** would otherwise compile from that expression and upload to the kernel. That program is invoked for each packet and it decides whether the **tcpdump** process should receive a copy of it.+Initially, BPF (the **extended** part was added when x64 architectures appeared ca. 2004) was used as a filtering criteria for network ​packet captures, limiting the amount of data copied to a userspace process for analysis. This is still used to this day. Try running **tcpdump <​expression>​** and adding the **-d** flag. Instead of actually listening for packets, this will dump the BPF program that **tcpdump** would otherwise compile from that expression and upload to the kernel. That program is invoked for each packet and it decides whether the **tcpdump** process should receive a copy of it.
  
 More recently (since approx. 2012), eBPF has been used in cloud native solutions such as [[https://​cilium.io/​|Cilium]] for profiling, resource observability and network policy enforcement. Technologies such as these have been long used by Netflix and Meta internally and are now becoming increasingly more relevant. You can find more information about this topic in [[https://​isovalent.com/​blog/​post/​cilium-up-and-running/#​cilium-up-and-running-is-finally-available-and-ready-for-download|Cilium:​ Up and Running]], a recent book released by Isovalent, a company specialized in microservice architectures that was acquired by Cisco in 2024 to help improve their inter-cloud security technologies. More recently (since approx. 2012), eBPF has been used in cloud native solutions such as [[https://​cilium.io/​|Cilium]] for profiling, resource observability and network policy enforcement. Technologies such as these have been long used by Netflix and Meta internally and are now becoming increasingly more relevant. You can find more information about this topic in [[https://​isovalent.com/​blog/​post/​cilium-up-and-running/#​cilium-up-and-running-is-finally-available-and-ready-for-download|Cilium:​ Up and Running]], a recent book released by Isovalent, a company specialized in microservice architectures that was acquired by Cisco in 2024 to help improve their inter-cloud security technologies.
  
-=== [00p] Task A - Hello World ===+=== [0p] Task A - Hello World ===
  
 [[https://​man.archlinux.org/​man/​extra/​bpftrace/​bpftrace.8.en|bpftrace]] is a high-level scripting language that can be compiled into an eBPF program. This is similar to a **tcpdump** expression but implements more complex logic and can be used to //​instrument//​ kernel functions. After installing the package, try running it on your system (**sudo** may be required): [[https://​man.archlinux.org/​man/​extra/​bpftrace/​bpftrace.8.en|bpftrace]] is a high-level scripting language that can be compiled into an eBPF program. This is similar to a **tcpdump** expression but implements more complex logic and can be used to //​instrument//​ kernel functions. After installing the package, try running it on your system (**sudo** may be required):
Line 71: Line 71:
   * A [[https://​bpftrace.org/​docs/​release_025/​language#​filterspredicates|predicate]] specified between the probe name and the action block.   * A [[https://​bpftrace.org/​docs/​release_025/​language#​filterspredicates|predicate]] specified between the probe name and the action block.
 </​note>​ </​note>​
 +
 +<​solution -hidden>
 +<code bash>
 +$ sudo bpftrace -e '​tracepoint:​syscalls:​sys_exit_read /args.ret < 0/ { printf("​%s (%d): %d\n", comm, pid, args.ret) }'
 +    kitty (8441): -11
 +    kitty (8441): -11
 +    libinput-connec (1357): -11
 +
 +$ errno 11
 +    EAGAIN 11 Resource temporarily unavailable ​
 +</​code>​
 +</​solution>​
  
 === [10p] Task D - Count read bytes === === [10p] Task D - Count read bytes ===
Line 83: Line 95:
  
 Make sure you filter out negative return values and execute your **bpftrace** script. Let it run for a few seconds, then interrupt it via a SIGINT (i.e., //Ctrl + C//). When unloading the probes and before terminating the process, all maps will be printed to //stdout//. Make sure you filter out negative return values and execute your **bpftrace** script. Let it run for a few seconds, then interrupt it via a SIGINT (i.e., //Ctrl + C//). When unloading the probes and before terminating the process, all maps will be printed to //stdout//.
 +
 +<​solution -hidden>
 +<code bash>
 +$ sudo bpftrace -e '​tracepoint:​syscalls:​sys_exit_read /args.ret > 0/ { @read_bytes[comm] += args.ret }'
 +</​code>​
 +</​solution>​
 +
 +== Periodic statistics ==
 +
 +Let's say you want to display these statistics every 2 seconds and reset the counters after each print. Make it feel more like **vmstat**.
 +
 +Use the [[https://​bpftrace.org/​docs/​release_025/​language#​interval|interval]] probe to achieve this. You can ''​print()''​ the map and then ''​clear()''​ it to reset its contents.
 +
 +<​solution -hidden>
 +<code bash>
 +$ sudo bpftrace -e '​tracepoint:​syscalls:​sys_exit_read /args.ret > 0/ { @read_bytes[comm] += args.ret } interval:​s:​2 { print(@read_bytes);​ printf("​\n"​);​ clear(@read_bytes) }'
 +</​code>​
 +</​solution>​
  
 === [5p] Task E - Built-in histogram function === === [5p] Task E - Built-in histogram function ===
  
 Use the [[https://​bpftrace.org/​docs/​release_025/​stdlib#​hist|hist()]] eBPF helper to visualize the distribution of bytes read for each syscall. The data that you visualize is not the total bytes read, but how many **read()** calls returned a value that fits within that specific log2 bucket. Use the [[https://​bpftrace.org/​docs/​release_025/​stdlib#​hist|hist()]] eBPF helper to visualize the distribution of bytes read for each syscall. The data that you visualize is not the total bytes read, but how many **read()** calls returned a value that fits within that specific log2 bucket.
 +
 +<​solution -hidden>
 +<code bash>
 +$ sudo bpftrace -e '​tracepoint:​syscalls:​sys_exit_read { @ = hist(args.ret) }'
 +    @:
 +    (..., 0)             303 |@@                                                  |
 +    [0]                  531 |@@@@                                                |
 +    [1]                 6246 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
 +    [2, 4)                10 |                                                    |
 +    [4, 8)                44 |                                                    |
 +    [8, 16)              725 |@@@@@@ ​                                             |
 +    [16, 32)              22 |                                                    |
 +    [32, 64)             401 |@@@                                                 |
 +    [64, 128)             32 |                                                    |
 +    [128, 256)            55 |                                                    |
 +    [256, 512)            85 |                                                    |
 +    [512, 1K)            347 |@@                                                  |
 +    [1K, 2K)             104 |                                                    |
 +    [2K, 4K)             279 |@@                                                  |
 +    [4K, 8K)              38 |                                                    |
 +    [8K, 16K)             15 |                                                    |
 +    [16K, 32K)            10 |                                                    |
 +    [32K, 64K)             1 |                                                    |
 +</​code>​
 +</​solution>​
ep/labs/05/contents/tasks/ex3.1774898111.txt.gz ยท Last modified: 2026/03/30 22:15 by radu.mantu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0