-
Notifications
You must be signed in to change notification settings - Fork 4k
libbpf-tools: add tcpdrop to trace TCP packet drops #5329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Added tcpdrop tool, consisting of tcpdrop.bpf.c and tcpdrop.c, to trace TCP kernel-dropped packets using eBPF. Supports IPv4/IPv6 filtering and network namespace filtering, with output including timestamp, PID, IP addresses, ports, TCP state, and drop reason. Based on tcptop(8) from BCC. Signed-off-by: Lance Yang <lance.yang@linux.dev> Signed-off-by: Zi Li <zi.li@linux.dev> Signed-off-by: Amaindex <amaindex@outlook.com>
Hi @chenhengqi , we’ve got a C version of tcpdrop in this PR (#5329), sticking close to the Python version’s features and options. Could you take a peek when you’ve got a sec? Would love your thoughts :) |
Hi @ekyooo and @chenhengqi , Thanks for the great feedback! I've made the following updates based on your suggestions:
Please take a look and let me know if there's anything else I can tweak! |
Hi @chenhengqi , Regarding your suggestion to copy reason enums from the kernel for tcpdrop, we previously used this approach in tcpdrop.py. However, recent experience shows these enums vary across kernel versions and distros, and they're easy to verify. So, I think dynamic loading via parse_reason_enum is more robust. It might be good to update tcpdrop.py to match this approach for consistency. What do you think, or is there another way to handle this? |
- Use ksyms__load and ksyms__map_addr for kernel symbol resolution. - Follow Linux kernel coding style in tcpdrop.bpf.c and tcpdrop.c. - Optimize IPv6 address handling with __u32 arrays and in6_u.u6_addr32. - Remove bpf_printk debug statements from tcpdrop.bpf.c. - Add /tcpdrop to .gitignore to exclude the binary. - Define event struct in tcpdrop.h to prevent duplicate definitions. - Check drop reason with bpf_core_field_exists in tcpdrop.bpf.c. Signed-off-by: Zi Li <zi.li@linux.dev> Signed-off-by: Amaindex <amaindex@outlook.com>
Do you have an example of |
Take
This is reflected in the tracepoint format for Now, fast forward to kernel v6.15.4, and things shift in
The tracepoint format in v6.15.4 confirms this, with Considering the skb_drop_reason index changes across kernel versions, parse_reason_enum for dynamic loading feels more adaptable than hardcoding the enums. |
Sounds reasonable. I am OK with this approach. |
Remove print_drop_reasons function and replace its call with a warning message in main when parse_reason_enum fails. Signed-off-by: Zi Li <zi.li@linux.dev> Signed-off-by: Amaindex <amaindex@outlook.com>
Hi @chenhengqi , |
Some comments are not resolved, please check. |
…cpdrop Move ipv4_only, ipv6_only, and netns_id to rodata section for better memory management. Optimize tcpdrop.bpf.c by declaring variables upfront and reordering operations for clarity. Update event struct to place stack_id correctly. Fix missing newlines at file ends. Signed-off-by: Zi Li <zi.li@linux.dev> Signed-off-by: Amaindex <amaindex@outlook.com>
Hi @chenhengqi , |
libbpf-tools/tcpdrop.bpf.c
Outdated
event->drop_reason = -1; | ||
} | ||
|
||
if (bpf_ringbuf_query(&events, BPF_RB_AVAIL_DATA) >= 511) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of bpf_ringbuf_query
here ?
libbpf-tools/tcpdrop.bpf.c
Outdated
protocol = args->protocol; | ||
if (protocol != ETH_P_IP && protocol != ETH_P_IPV6) { | ||
bpf_ringbuf_discard(event, 0); | ||
return 0; | ||
} | ||
if (ipv4_only && protocol != ETH_P_IP) { | ||
bpf_ringbuf_discard(event, 0); | ||
return 0; | ||
} | ||
if (ipv6_only && protocol != ETH_P_IPV6) { | ||
bpf_ringbuf_discard(event, 0); | ||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check these before bpf_ringbuf_reserve()
so that we don't have to use many bpf_ringbuf_discard() in each branch.
Defer the BPF ring buffer event allocation in tcpdrop.bpf.c until all preliminary checks are passed, reducing unnecessary discards and improving performance. This ensures the event is only reserved when the skb meets all processing conditions, minimizing resource waste. Signed-off-by: Zi Li <zi.li@linux.dev> Signed-off-by: Amaindex <amaindex@outlook.com>
Hi @chenhengqi, |
Added tcpdrop tool, consisting of tcpdrop.bpf.c and tcpdrop.c, to trace TCP kernel-dropped packets using eBPF. Supports IPv4/IPv6 filtering and network namespace filtering, with output including timestamp, PID, IP addresses, ports, TCP state, and drop reason. Based on tcptop(8) from BCC.