Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/yutarohayakawa/ipftrace2
A packet oriented Linux kernel function call tracer
https://github.com/yutarohayakawa/ipftrace2
bpf ebpf linux-kernel network tracing
Last synced: about 1 month ago
JSON representation
A packet oriented Linux kernel function call tracer
- Host: GitHub
- URL: https://github.com/yutarohayakawa/ipftrace2
- Owner: YutaroHayakawa
- License: other
- Created: 2020-03-17T16:53:52.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2024-04-14T02:35:14.000Z (7 months ago)
- Last Synced: 2024-10-12T07:41:56.150Z (about 1 month ago)
- Topics: bpf, ebpf, linux-kernel, network, tracing
- Language: C
- Homepage:
- Size: 17.1 MB
- Stars: 385
- Watchers: 15
- Forks: 16
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ipftrace2
`ipftrace2` is a tool which allows you to trace the journey of packets inside the Linux kernel. It is similar to `ftrace` in some sense, but you can trace **which flow has gone through which functions** inside the kernel which is usually more important information for the network people than **which functions are called** information provided by `ftrace`.
![demo](img/demo.gif)
## Requirements
- Architecture: x86_64
- Linux version: v4.17 or above
- Kernel config
- CONFIG_DEBUG_INFO_BTF=y
- CONFIG_KPROBES=y
- CONFIG_PERF_EVENTS=y
- CONFIG_BPF=y
- CONFIG_BPF_SYSCALL=y- CONFIG_DEBUG_INFO_BTF_MODULE=y (Optional)
- Enabling this allows ipftrace2 to trace kernel module's functions## Install
ipftrace2 is a single-binary application. You don't have to install any dependencies.
```
curl -OL https://github.com/YutaroHayakawa/ipftrace2/releases/latest/download/ipftrace2_amd64.tar.gz
tar xvf ipftrace2_amd64.tar.gz
sudo cp ipft /usr/local/bin/ipft
```## Basic usage
Run ipftrace2
```
sudo ipft -m 0xdeadbeef
```Mark the packets you are interested in
```
# Mark packets from/to 1.1.1.1
sudo iptables -t raw -A OUTPUT -d 1.1.1.1 -j MARK --set-mark 0xdeadbeef
sudo iptables -t raw -A PREROUTING -s 1.1.1.1 -j MARK --set-mark 0xdeadbeef
```Make some traffic
```
curl https://1.1.1.1
```Terminate `ipft` with `Ctrl-C` . Then, you should see the output.
## Feature highlight
#### Function tracer
Records function calls for packets. This is the default tracer.
```
$ sudo ipft -m 0xdeadbeef96976848684329 000 nf_checksum
96976848692769 000 nf_ip_checksum
96976848765647 000 tcp_v4_early_demux
96976848836855 000 ip_local_deliver
96976848840849 000 nf_hook_slow
96976848846012 000 ip_local_deliver_finish
96976848851032 000 ip_protocol_deliver_rcu```
#### Function graph tracer
Records function calls as well as function returns and visualizes the call depth.
```
$ sudo ipft -m 0xdeadbeef -t function_graph480959550911894 000 ip_protocol_deliver_rcu() {
480959550913049 000 raw_local_deliver() {
480959550914188 000 }
480959550915380 000 tcp_v4_rcv() {
480959550916635 000 tcp_filter() {
480959550917812 000 sk_filter_trim_cap() {
480959550918999 000 security_sock_rcv_skb() {
480959550920116 000 }
480959550921258 000 }
480959550922397 000 }```
#### Raw JSON output
Generates raw tracing output to `stdout` in machine-readable JSON. You can implement your own visualizer with this feature.
```
$ sudo ipft -m 0xdeadbeef -t function_graph -o json{"packet_id":"0xffff8dee8aea9700","timestamp":25340022557487,"processor_id":0,"function":"validate_xmit_xfrm","is_return":false}
{"packet_id":"0xffff8dee8aea9700","timestamp":25340022558860,"processor_id":0,"function":"validate_xmit_xfrm","is_return":true}
{"packet_id":"0xffff8dee8aea9700","timestamp":25340022560159,"processor_id":0,"function":"validate_xmit_skb","is_return":true}
{"packet_id":"0xffff8dee8aea9700","timestamp":25340022561440,"processor_id":0,"function":"validate_xmit_skb_list","is_return":true}
{"packet_id":"0xffff8dee8aea9700","timestamp":25340022572083,"processor_id":0,"function":"dev_hard_start_xmit","is_return":false}
{"packet_id":"0xffff8dee8aea9700","timestamp":25340022574087,"processor_id":0,"function":"skb_clone_tx_timestamp","is_return":false}
{"packet_id":"0xffff8dee8aea9700","timestamp":25340022575519,"processor_id":0,"function":"skb_clone_tx_timestamp","is_return":true}```
#### Custom tracing output
You can customize your tracing output by providing custom extension.
```
$ sudo ipft -m 0xdeadbeef -e example.c96976848684329 000 nf_checksum ( len: 2822 )
96976848692769 000 nf_ip_checksum ( len: 2822 )
96976848765647 000 tcp_v4_early_demux ( len: 2822 )
96976848836855 000 ip_local_deliver ( len: 2822 )
96976848840849 000 nf_hook_slow ( len: 2822 )
96976848846012 000 ip_local_deliver_finish ( len: 2822 )
96976848851032 000 ip_protocol_deliver_rcu ( len: 2802 )```
Of course, you can use scripting together with JSON output.
```
$ sudo ipft -m 0xdeadbeef -e example.c -o json{"packet_id":"0xffff935007672900","timestamp":169530008921,"processor_id":0,"function":"__ip_finish_output","is_return":false,"len":"40"}
{"packet_id":"0xffff935007672900","timestamp":169530010558,"processor_id":0,"function":"ip_finish_output2","is_return":false,"len":"40"}
{"packet_id":"0xffff935007672900","timestamp":169530012511,"processor_id":0,"function":"dev_queue_xmit","is_return":false,"len":"54"}
{"packet_id":"0xffff935007672900","timestamp":169530014441,"processor_id":0,"function":"__dev_queue_xmit","is_return":false,"len":"54"}
{"packet_id":"0xffff935007672900","timestamp":169530017180,"processor_id":0,"function":"netdev_core_pick_tx","is_return":false,"len":"54"}```
## Usage
```
Usage: ipft [OPTIONS]Options:
-b, --backend [BACKEND] Specify trace backend
-e, --extension [PATH] Path to extension (the file name must be have .c, .o, or .lua suffix)
--gen [TARGET] Generate something
-h, --help Show this text
-l, --list List functions
-m, --mark [NUMBER] Trace the packet marked with [required]
, --mask [NUMBER] Only match to the bits masked with given bitmask (default: 0xffffffff)
, --module-regex [REGEX] Filter the function to trace by regex for kernel module's name
-o, --output [OUTPUT-FORMAT] Specify output format
-r, --regex [REGEX] Filter the function to trace with regex
-s, --script [PATH] Path to extension Lua script (deprecated, use -e instead)
-t, --tracer [TRACER-TYPE] Specify tracer type
-v, --verbose Turn on debug message
, --perf-page-count [NUMBER] See page_count of perf_event_open(2) man page (default: 8)
, --perf-sample-period [NUMBER] See sample_period of perf_event_open(2) man page (default: 1)
, --perf-wakeup-events [NUMBER] See wakeup_events of perf_event_open(2) man page (default: 1)
, --no-set-rlimit Don't set rlimit
, --enable-probe-server Enable probe server
, --probe-server-port Set probe server portBACKEND := { kprobe, ftrace, kprobe-multi }
OUTPUT-FORMAT := { aggregate, json }
TRACER-TYPE := { function, function_graph (experimental) }
TARGET := { bpf-module-skeleton, bpf-module-header }
```## Further reading
- [BPF extension manual (recommended)](docs/bpf_extension.md) gives you the guide guide to customize your tracing output
- [Lua extension manual (deprecated)](docs/lua_extension.md) gives you the guide to customize your tracing output in legacy Lua extension
- With [output specification](docs/output.md), you can learn how to interpret the output
- Understanding [marking](docs/marking.md) helps you a lot for fully utilizing the power of ipftrace2
- Please check this [doc](docs/internals.md) out if you are interested in the ipftrace2 internals