ipftrace2

一个面向数据包的 Linux 内核函数调用追踪器。「A packet oriented Linux kernel function call tracer」

Github星跟蹤圖

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

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 0xdeadbeef
<skip...>
96976848684329       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
<skip...>

Function graph tracer

Records function calls as well as function returns and visualizes the call depth.

$ sudo ipft -m 0xdeadbeef -t function_graph
<skip...>
480959550911894      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     }
<skip...>

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
<skip...>
{"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}
<skip...>

Custom tracing output

You can customize your tracing output by providing custom extension.

$ sudo ipft -m 0xdeadbeef -e example.c
<skip...>
96976848684329       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 )
<skip...>

Of course, you can use scripting together with JSON output.

$ sudo ipft -m 0xdeadbeef -e example.c -o json
<skip...>
{"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"}
<skip...>

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 <mark> [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 port

BACKEND       := { kprobe, ftrace, kprobe-multi }
OUTPUT-FORMAT := { aggregate, json }
TRACER-TYPE   := { function, function_graph (experimental) }
TARGET        := { bpf-module-skeleton, bpf-module-header }

Further reading

主要指標

概覽
名稱與所有者YutaroHayakawa/ipftrace2
主編程語言C
編程語言C (語言數: 6)
平台
許可證Other
所有者活动
創建於2020-03-17 16:53:52
推送於2024-04-14 02:35:14
最后一次提交2024-04-06 16:46:37
發布數24
最新版本名稱v0.10.1 (發布於 )
第一版名稱v0.0.1 (發布於 )
用户参与
星數401
關注者數14
派生數17
提交數476
已啟用問題?
問題數10
打開的問題數1
拉請求數4
打開的拉請求數0
關閉的拉請求數4
项目设置
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?