1+ #include "tcpdrop.h"
12#include "vmlinux.h"
2- #include <bpf/bpf_helpers.h>
33#include <bpf/bpf_core_read.h>
4- #include <bpf/bpf_tracing.h>
54#include <bpf/bpf_endian.h>
5+ #include <bpf/bpf_helpers.h>
6+ #include <bpf/bpf_tracing.h>
67
78#ifndef AF_INET
89#define AF_INET 2
910#endif
1011#ifndef AF_INET6
1112#define AF_INET6 10
1213#endif
13- #ifndef TASK_COMM_LEN
14- #define TASK_COMM_LEN 16
15- #endif
1614#ifndef ETH_P_IP
1715#define ETH_P_IP 0x0800
1816#endif
1917#ifndef ETH_P_IPV6
2018#define ETH_P_IPV6 0x86dd
2119#endif
2220
23- struct event {
24- u64 timestamp ;
25- u32 pid ;
26- u32 drop_reason ;
27- u32 ip_version ; // 4 for IPv4, 6 for IPv6
28- union {
29- u32 saddr_v4 ;
30- unsigned __int128 saddr_v6 ;
31- };
32- union {
33- u32 daddr_v4 ;
34- unsigned __int128 daddr_v6 ;
35- };
36- u16 sport ;
37- u16 dport ;
38- u8 state ;
39- u8 tcpflags ;
40- char comm [TASK_COMM_LEN ];
41- u32 stack_id ;
42- };
43-
4421struct {
45- __uint (type , BPF_MAP_TYPE_RINGBUF );
46- __uint (max_entries , 512 );
22+ __uint (type , BPF_MAP_TYPE_RINGBUF );
23+ __uint (max_entries , 512 );
4724} events SEC (".maps" );
4825
4926#define MAX_STACK_DEPTH 15
5027struct {
51- __uint (type , BPF_MAP_TYPE_STACK_TRACE );
52- __uint (max_entries , 512 );
53- __uint (key_size , sizeof (u32 ));
54- __uint (value_size , MAX_STACK_DEPTH * sizeof (u64 ));
28+ __uint (type , BPF_MAP_TYPE_STACK_TRACE );
29+ __uint (max_entries , 512 );
30+ __uint (key_size , sizeof (u32 ));
31+ __uint (value_size , MAX_STACK_DEPTH * sizeof (u64 ));
5532} stack_traces SEC (".maps" );
5633
5734char ipv4_only = 0 ;
5835char ipv6_only = 0 ;
5936__u32 netns_id = 0 ;
6037
6138SEC ("tracepoint/skb/kfree_skb" )
62- int tp__skb_free_skb (struct trace_event_raw_kfree_skb * args )
39+ int tp__skb_free_skb (struct trace_event_raw_kfree_skb * args )
6340{
64- if (args -> reason <= SKB_DROP_REASON_NOT_SPECIFIED ) {
65- return 0 ;
66- }
67-
68- if (bpf_ringbuf_query (& events , BPF_RB_AVAIL_DATA ) >= 511 ) {
69- bpf_printk ("Ring buffer is almost full\n" );
70- return 0 ;
71- }
72-
73- u64 pid_tgid = bpf_get_current_pid_tgid ();
74- u32 pid = pid_tgid >> 32 ;
75-
76- struct sk_buff * skb = args -> skbaddr ;
77- if (!skb ) {
78- return 0 ;
79- }
80- struct sock * sk = NULL ;
81- bpf_core_read (& sk , sizeof (sk ), & skb -> sk );
82-
83- // Get packet headers
84- void * head ;
85- u16 network_header , transport_header ;
86- if (bpf_core_read (& head , sizeof (head ), & skb -> head ) ||
87- bpf_core_read (& network_header , sizeof (network_header ), & skb -> network_header ) ||
88- bpf_core_read (& transport_header , sizeof (transport_header ), & skb -> transport_header )) {
89- bpf_printk ("Failed to read skb headers\n" );
90- return 0 ;
91- }
92-
93- // Check protocol and filter by IP family
94- u16 protocol = args -> protocol ;
95- if (protocol != ETH_P_IP && protocol != ETH_P_IPV6 ) {
96- bpf_printk ("Unsupported protocol: %u\n" , protocol );
97- return 0 ;
98- }
99- if (ipv4_only && protocol != ETH_P_IP ) {
100- return 0 ;
101- }
102- if (ipv6_only && protocol != ETH_P_IPV6 ) {
103- return 0 ;
104- }
105-
106- // Filter by network namespace
107- if (netns_id && sk ) {
108- struct net * net = NULL ;
109- bpf_core_read (& net , sizeof (net ), & sk -> __sk_common .skc_net .net );
110- if (net ) {
111- u32 inum ;
112- bpf_core_read (& inum , sizeof (inum ), & net -> ns .inum );
113- if (inum != netns_id ) {
114- bpf_printk ("Skipping packet from different netns: %u != %u\n" , inum , netns_id );
115- return 0 ;
116- }
117- }
118- }
119-
120- struct event * event = bpf_ringbuf_reserve (& events , sizeof (* event ), 0 );
121- if (!event ) {
122- return 0 ;
123- }
124-
125- event -> timestamp = bpf_ktime_get_ns ();
126- event -> pid = pid ;
127- event -> drop_reason = args -> reason ;
128- bpf_get_current_comm (& event -> comm , sizeof (event -> comm ));
129- event -> stack_id = bpf_get_stackid (args , & stack_traces , 0 );
130- event -> state = 127 ;
131- if (sk ) {
132- u8 state ;
133- if (!bpf_core_read (& state , sizeof (state ), & sk -> __sk_common .skc_state )) {
134- event -> state = state ;
135- }
136- }
137-
138- if (protocol == ETH_P_IP ) {
139- struct iphdr ip ;
140- if (bpf_core_read (& ip , sizeof (ip ), head + network_header )) {
141- bpf_ringbuf_discard (event , 0 );
142- return 0 ;
143- }
144- if (ip .protocol != IPPROTO_TCP ) {
145- bpf_ringbuf_discard (event , 0 );
146- return 0 ;
147- }
148- struct tcphdr tcp ;
149- if (bpf_core_read (& tcp , sizeof (tcp ), head + transport_header )) {
150- bpf_ringbuf_discard (event , 0 );
151- return 0 ;
152- }
153- event -> ip_version = 4 ;
154- event -> saddr_v4 = ip .saddr ;
155- event -> daddr_v4 = ip .daddr ;
156- event -> sport = bpf_ntohs (tcp .source );
157- event -> dport = bpf_ntohs (tcp .dest );
158- event -> tcpflags = ((u8 * )& tcp )[13 ];
159- } else {
160- struct ipv6hdr ip6 ;
161- if (bpf_core_read (& ip6 , sizeof (ip6 ), head + network_header )) {
162- bpf_ringbuf_discard (event , 0 );
163- return 0 ;
164- }
165- if (ip6 .nexthdr != IPPROTO_TCP ) {
166- bpf_ringbuf_discard (event , 0 );
167- return 0 ;
168- }
169- struct tcphdr tcp ;
170- if (bpf_core_read (& tcp , sizeof (tcp ), head + transport_header )) {
171- bpf_ringbuf_discard (event , 0 );
172- return 0 ;
173- }
174- event -> ip_version = 6 ;
175- bpf_core_read (& event -> saddr_v6 , sizeof (event -> saddr_v6 ), & ip6 .saddr );
176- bpf_core_read (& event -> daddr_v6 , sizeof (event -> daddr_v6 ), & ip6 .daddr );
177- event -> sport = bpf_ntohs (tcp .source );
178- event -> dport = bpf_ntohs (tcp .dest );
179- event -> tcpflags = ((u8 * )& tcp )[13 ];
180- }
181-
182- bpf_ringbuf_submit (event , 0 );
183- return 0 ;
41+ struct event * event = bpf_ringbuf_reserve (& events , sizeof (* event ), 0 );
42+ if (!event ) {
43+ return 0 ;
44+ }
45+
46+ // Check if reason field is available
47+ if (bpf_core_field_exists (args -> reason )) {
48+ if (args -> reason <= SKB_DROP_REASON_NOT_SPECIFIED ) {
49+ bpf_ringbuf_discard (event , 0 );
50+ return 0 ;
51+ }
52+ event -> drop_reason = args -> reason ;
53+ } else {
54+ event -> drop_reason = -1 ;
55+ }
56+
57+ if (bpf_ringbuf_query (& events , BPF_RB_AVAIL_DATA ) >= 511 ) {
58+ bpf_ringbuf_discard (event , 0 );
59+ return 0 ;
60+ }
61+
62+ u64 pid_tgid = bpf_get_current_pid_tgid ();
63+ u32 pid = pid_tgid >> 32 ;
64+
65+ struct sk_buff * skb = args -> skbaddr ;
66+ if (!skb ) {
67+ bpf_ringbuf_discard (event , 0 );
68+ return 0 ;
69+ }
70+ struct sock * sk = NULL ;
71+ bpf_core_read (& sk , sizeof (sk ), & skb -> sk );
72+
73+ // Get packet headers
74+ void * head ;
75+ u16 network_header , transport_header ;
76+ if (bpf_core_read (& head , sizeof (head ), & skb -> head ) ||
77+ bpf_core_read (& network_header , sizeof (network_header ),
78+ & skb -> network_header ) ||
79+ bpf_core_read (& transport_header , sizeof (transport_header ),
80+ & skb -> transport_header )) {
81+ bpf_ringbuf_discard (event , 0 );
82+ return 0 ;
83+ }
84+
85+ // Check protocol and filter by IP family
86+ u16 protocol = args -> protocol ;
87+ if (protocol != ETH_P_IP && protocol != ETH_P_IPV6 ) {
88+ bpf_ringbuf_discard (event , 0 );
89+ return 0 ;
90+ }
91+ if (ipv4_only && protocol != ETH_P_IP ) {
92+ bpf_ringbuf_discard (event , 0 );
93+ return 0 ;
94+ }
95+ if (ipv6_only && protocol != ETH_P_IPV6 ) {
96+ bpf_ringbuf_discard (event , 0 );
97+ return 0 ;
98+ }
99+
100+ // Filter by network namespace
101+ if (netns_id && sk ) {
102+ struct net * net = NULL ;
103+ bpf_core_read (& net , sizeof (net ), & sk -> __sk_common .skc_net .net );
104+ if (net ) {
105+ u32 inum ;
106+ bpf_core_read (& inum , sizeof (inum ), & net -> ns .inum );
107+ if (inum != netns_id ) {
108+ bpf_ringbuf_discard (event , 0 );
109+ return 0 ;
110+ }
111+ }
112+ }
113+
114+ event -> timestamp = bpf_ktime_get_ns ();
115+ event -> pid = pid ;
116+ bpf_get_current_comm (& event -> comm , sizeof (event -> comm ));
117+ event -> stack_id = bpf_get_stackid (args , & stack_traces , 0 );
118+ event -> state = 127 ;
119+ if (sk ) {
120+ u8 state ;
121+ if (!bpf_core_read (& state , sizeof (state ),
122+ & sk -> __sk_common .skc_state )) {
123+ event -> state = state ;
124+ }
125+ }
126+
127+ if (protocol == ETH_P_IP ) {
128+ struct iphdr ip ;
129+ if (bpf_core_read (& ip , sizeof (ip ), head + network_header )) {
130+ bpf_ringbuf_discard (event , 0 );
131+ return 0 ;
132+ }
133+ if (ip .protocol != IPPROTO_TCP ) {
134+ bpf_ringbuf_discard (event , 0 );
135+ return 0 ;
136+ }
137+ struct tcphdr tcp ;
138+ if (bpf_core_read (& tcp , sizeof (tcp ), head + transport_header )) {
139+ bpf_ringbuf_discard (event , 0 );
140+ return 0 ;
141+ }
142+ event -> ip_version = 4 ;
143+ event -> saddr_v4 = ip .saddr ;
144+ event -> daddr_v4 = ip .daddr ;
145+ event -> sport = bpf_ntohs (tcp .source );
146+ event -> dport = bpf_ntohs (tcp .dest );
147+ event -> tcpflags = ((u8 * ) & tcp )[13 ];
148+ } else {
149+ struct ipv6hdr ip6 ;
150+ if (bpf_core_read (& ip6 , sizeof (ip6 ), head + network_header )) {
151+ bpf_ringbuf_discard (event , 0 );
152+ return 0 ;
153+ }
154+ if (ip6 .nexthdr != IPPROTO_TCP ) {
155+ bpf_ringbuf_discard (event , 0 );
156+ return 0 ;
157+ }
158+ struct tcphdr tcp ;
159+ if (bpf_core_read (& tcp , sizeof (tcp ), head + transport_header )) {
160+ bpf_ringbuf_discard (event , 0 );
161+ return 0 ;
162+ }
163+ event -> ip_version = 6 ;
164+ bpf_core_read (& event -> saddr_v6 , sizeof (event -> saddr_v6 ),
165+ & ip6 .saddr .in6_u .u6_addr32 );
166+ bpf_core_read (& event -> daddr_v6 , sizeof (event -> daddr_v6 ),
167+ & ip6 .daddr .in6_u .u6_addr32 );
168+ event -> sport = bpf_ntohs (tcp .source );
169+ event -> dport = bpf_ntohs (tcp .dest );
170+ event -> tcpflags = ((u8 * ) & tcp )[13 ];
171+ }
172+
173+ bpf_ringbuf_submit (event , 0 );
174+ return 0 ;
184175}
185176
186177char _license [] SEC ("license" ) = "Dual BSD/GPL" ;
0 commit comments