1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #undef TRACE_SYSTEM |
3 | #define TRACE_SYSTEM tcp |
4 | |
5 | #if !defined(_TRACE_TCP_H) || defined(TRACE_HEADER_MULTI_READ) |
6 | #define _TRACE_TCP_H |
7 | |
8 | #include <linux/ipv6.h> |
9 | #include <linux/tcp.h> |
10 | #include <linux/tracepoint.h> |
11 | #include <net/ipv6.h> |
12 | #include <net/tcp.h> |
13 | #include <linux/sock_diag.h> |
14 | |
15 | #define TP_STORE_V4MAPPED(__entry, saddr, daddr) \ |
16 | do { \ |
17 | struct in6_addr *pin6; \ |
18 | \ |
19 | pin6 = (struct in6_addr *)__entry->saddr_v6; \ |
20 | ipv6_addr_set_v4mapped(saddr, pin6); \ |
21 | pin6 = (struct in6_addr *)__entry->daddr_v6; \ |
22 | ipv6_addr_set_v4mapped(daddr, pin6); \ |
23 | } while (0) |
24 | |
25 | #if IS_ENABLED(CONFIG_IPV6) |
26 | #define TP_STORE_ADDRS(__entry, saddr, daddr, saddr6, daddr6) \ |
27 | do { \ |
28 | if (sk->sk_family == AF_INET6) { \ |
29 | struct in6_addr *pin6; \ |
30 | \ |
31 | pin6 = (struct in6_addr *)__entry->saddr_v6; \ |
32 | *pin6 = saddr6; \ |
33 | pin6 = (struct in6_addr *)__entry->daddr_v6; \ |
34 | *pin6 = daddr6; \ |
35 | } else { \ |
36 | TP_STORE_V4MAPPED(__entry, saddr, daddr); \ |
37 | } \ |
38 | } while (0) |
39 | #else |
40 | #define TP_STORE_ADDRS(__entry, saddr, daddr, saddr6, daddr6) \ |
41 | TP_STORE_V4MAPPED(__entry, saddr, daddr) |
42 | #endif |
43 | |
44 | /* |
45 | * tcp event with arguments sk and skb |
46 | * |
47 | * Note: this class requires a valid sk pointer; while skb pointer could |
48 | * be NULL. |
49 | */ |
50 | DECLARE_EVENT_CLASS(tcp_event_sk_skb, |
51 | |
52 | TP_PROTO(const struct sock *sk, const struct sk_buff *skb), |
53 | |
54 | TP_ARGS(sk, skb), |
55 | |
56 | TP_STRUCT__entry( |
57 | __field(const void *, skbaddr) |
58 | __field(const void *, skaddr) |
59 | __field(int, state) |
60 | __field(__u16, sport) |
61 | __field(__u16, dport) |
62 | __field(__u16, family) |
63 | __array(__u8, saddr, 4) |
64 | __array(__u8, daddr, 4) |
65 | __array(__u8, saddr_v6, 16) |
66 | __array(__u8, daddr_v6, 16) |
67 | ), |
68 | |
69 | TP_fast_assign( |
70 | const struct inet_sock *inet = inet_sk(sk); |
71 | __be32 *p32; |
72 | |
73 | __entry->skbaddr = skb; |
74 | __entry->skaddr = sk; |
75 | __entry->state = sk->sk_state; |
76 | |
77 | __entry->sport = ntohs(inet->inet_sport); |
78 | __entry->dport = ntohs(inet->inet_dport); |
79 | __entry->family = sk->sk_family; |
80 | |
81 | p32 = (__be32 *) __entry->saddr; |
82 | *p32 = inet->inet_saddr; |
83 | |
84 | p32 = (__be32 *) __entry->daddr; |
85 | *p32 = inet->inet_daddr; |
86 | |
87 | TP_STORE_ADDRS(__entry, inet->inet_saddr, inet->inet_daddr, |
88 | sk->sk_v6_rcv_saddr, sk->sk_v6_daddr); |
89 | ), |
90 | |
91 | TP_printk("family=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c state=%s" , |
92 | show_family_name(__entry->family), |
93 | __entry->sport, __entry->dport, __entry->saddr, __entry->daddr, |
94 | __entry->saddr_v6, __entry->daddr_v6, |
95 | show_tcp_state_name(__entry->state)) |
96 | ); |
97 | |
98 | DEFINE_EVENT(tcp_event_sk_skb, tcp_retransmit_skb, |
99 | |
100 | TP_PROTO(const struct sock *sk, const struct sk_buff *skb), |
101 | |
102 | TP_ARGS(sk, skb) |
103 | ); |
104 | |
105 | /* |
106 | * skb of trace_tcp_send_reset is the skb that caused RST. In case of |
107 | * active reset, skb should be NULL |
108 | */ |
109 | DEFINE_EVENT(tcp_event_sk_skb, tcp_send_reset, |
110 | |
111 | TP_PROTO(const struct sock *sk, const struct sk_buff *skb), |
112 | |
113 | TP_ARGS(sk, skb) |
114 | ); |
115 | |
116 | /* |
117 | * tcp event with arguments sk |
118 | * |
119 | * Note: this class requires a valid sk pointer. |
120 | */ |
121 | DECLARE_EVENT_CLASS(tcp_event_sk, |
122 | |
123 | TP_PROTO(struct sock *sk), |
124 | |
125 | TP_ARGS(sk), |
126 | |
127 | TP_STRUCT__entry( |
128 | __field(const void *, skaddr) |
129 | __field(__u16, sport) |
130 | __field(__u16, dport) |
131 | __field(__u16, family) |
132 | __array(__u8, saddr, 4) |
133 | __array(__u8, daddr, 4) |
134 | __array(__u8, saddr_v6, 16) |
135 | __array(__u8, daddr_v6, 16) |
136 | __field(__u64, sock_cookie) |
137 | ), |
138 | |
139 | TP_fast_assign( |
140 | struct inet_sock *inet = inet_sk(sk); |
141 | __be32 *p32; |
142 | |
143 | __entry->skaddr = sk; |
144 | |
145 | __entry->sport = ntohs(inet->inet_sport); |
146 | __entry->dport = ntohs(inet->inet_dport); |
147 | __entry->family = sk->sk_family; |
148 | |
149 | p32 = (__be32 *) __entry->saddr; |
150 | *p32 = inet->inet_saddr; |
151 | |
152 | p32 = (__be32 *) __entry->daddr; |
153 | *p32 = inet->inet_daddr; |
154 | |
155 | TP_STORE_ADDRS(__entry, inet->inet_saddr, inet->inet_daddr, |
156 | sk->sk_v6_rcv_saddr, sk->sk_v6_daddr); |
157 | |
158 | __entry->sock_cookie = sock_gen_cookie(sk); |
159 | ), |
160 | |
161 | TP_printk("family=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c sock_cookie=%llx" , |
162 | show_family_name(__entry->family), |
163 | __entry->sport, __entry->dport, |
164 | __entry->saddr, __entry->daddr, |
165 | __entry->saddr_v6, __entry->daddr_v6, |
166 | __entry->sock_cookie) |
167 | ); |
168 | |
169 | DEFINE_EVENT(tcp_event_sk, tcp_receive_reset, |
170 | |
171 | TP_PROTO(struct sock *sk), |
172 | |
173 | TP_ARGS(sk) |
174 | ); |
175 | |
176 | DEFINE_EVENT(tcp_event_sk, tcp_destroy_sock, |
177 | |
178 | TP_PROTO(struct sock *sk), |
179 | |
180 | TP_ARGS(sk) |
181 | ); |
182 | |
183 | DEFINE_EVENT(tcp_event_sk, tcp_rcv_space_adjust, |
184 | |
185 | TP_PROTO(struct sock *sk), |
186 | |
187 | TP_ARGS(sk) |
188 | ); |
189 | |
190 | TRACE_EVENT(tcp_retransmit_synack, |
191 | |
192 | TP_PROTO(const struct sock *sk, const struct request_sock *req), |
193 | |
194 | TP_ARGS(sk, req), |
195 | |
196 | TP_STRUCT__entry( |
197 | __field(const void *, skaddr) |
198 | __field(const void *, req) |
199 | __field(__u16, sport) |
200 | __field(__u16, dport) |
201 | __field(__u16, family) |
202 | __array(__u8, saddr, 4) |
203 | __array(__u8, daddr, 4) |
204 | __array(__u8, saddr_v6, 16) |
205 | __array(__u8, daddr_v6, 16) |
206 | ), |
207 | |
208 | TP_fast_assign( |
209 | struct inet_request_sock *ireq = inet_rsk(req); |
210 | __be32 *p32; |
211 | |
212 | __entry->skaddr = sk; |
213 | __entry->req = req; |
214 | |
215 | __entry->sport = ireq->ir_num; |
216 | __entry->dport = ntohs(ireq->ir_rmt_port); |
217 | __entry->family = sk->sk_family; |
218 | |
219 | p32 = (__be32 *) __entry->saddr; |
220 | *p32 = ireq->ir_loc_addr; |
221 | |
222 | p32 = (__be32 *) __entry->daddr; |
223 | *p32 = ireq->ir_rmt_addr; |
224 | |
225 | TP_STORE_ADDRS(__entry, ireq->ir_loc_addr, ireq->ir_rmt_addr, |
226 | ireq->ir_v6_loc_addr, ireq->ir_v6_rmt_addr); |
227 | ), |
228 | |
229 | TP_printk("family=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c" , |
230 | show_family_name(__entry->family), |
231 | __entry->sport, __entry->dport, |
232 | __entry->saddr, __entry->daddr, |
233 | __entry->saddr_v6, __entry->daddr_v6) |
234 | ); |
235 | |
236 | #include <trace/events/net_probe_common.h> |
237 | |
238 | TRACE_EVENT(tcp_probe, |
239 | |
240 | TP_PROTO(struct sock *sk, struct sk_buff *skb), |
241 | |
242 | TP_ARGS(sk, skb), |
243 | |
244 | TP_STRUCT__entry( |
245 | /* sockaddr_in6 is always bigger than sockaddr_in */ |
246 | __array(__u8, saddr, sizeof(struct sockaddr_in6)) |
247 | __array(__u8, daddr, sizeof(struct sockaddr_in6)) |
248 | __field(__u16, sport) |
249 | __field(__u16, dport) |
250 | __field(__u16, family) |
251 | __field(__u32, mark) |
252 | __field(__u16, data_len) |
253 | __field(__u32, snd_nxt) |
254 | __field(__u32, snd_una) |
255 | __field(__u32, snd_cwnd) |
256 | __field(__u32, ssthresh) |
257 | __field(__u32, snd_wnd) |
258 | __field(__u32, srtt) |
259 | __field(__u32, rcv_wnd) |
260 | __field(__u64, sock_cookie) |
261 | ), |
262 | |
263 | TP_fast_assign( |
264 | const struct tcphdr *th = (const struct tcphdr *)skb->data; |
265 | const struct inet_sock *inet = inet_sk(sk); |
266 | const struct tcp_sock *tp = tcp_sk(sk); |
267 | |
268 | memset(__entry->saddr, 0, sizeof(struct sockaddr_in6)); |
269 | memset(__entry->daddr, 0, sizeof(struct sockaddr_in6)); |
270 | |
271 | TP_STORE_ADDR_PORTS(__entry, inet, sk); |
272 | |
273 | /* For filtering use */ |
274 | __entry->sport = ntohs(inet->inet_sport); |
275 | __entry->dport = ntohs(inet->inet_dport); |
276 | __entry->mark = skb->mark; |
277 | __entry->family = sk->sk_family; |
278 | |
279 | __entry->data_len = skb->len - __tcp_hdrlen(th); |
280 | __entry->snd_nxt = tp->snd_nxt; |
281 | __entry->snd_una = tp->snd_una; |
282 | __entry->snd_cwnd = tcp_snd_cwnd(tp); |
283 | __entry->snd_wnd = tp->snd_wnd; |
284 | __entry->rcv_wnd = tp->rcv_wnd; |
285 | __entry->ssthresh = tcp_current_ssthresh(sk); |
286 | __entry->srtt = tp->srtt_us >> 3; |
287 | __entry->sock_cookie = sock_gen_cookie(sk); |
288 | ), |
289 | |
290 | TP_printk("family=%s src=%pISpc dest=%pISpc mark=%#x data_len=%d snd_nxt=%#x snd_una=%#x snd_cwnd=%u ssthresh=%u snd_wnd=%u srtt=%u rcv_wnd=%u sock_cookie=%llx" , |
291 | show_family_name(__entry->family), |
292 | __entry->saddr, __entry->daddr, __entry->mark, |
293 | __entry->data_len, __entry->snd_nxt, __entry->snd_una, |
294 | __entry->snd_cwnd, __entry->ssthresh, __entry->snd_wnd, |
295 | __entry->srtt, __entry->rcv_wnd, __entry->sock_cookie) |
296 | ); |
297 | |
298 | #define TP_STORE_ADDR_PORTS_SKB_V4(__entry, skb) \ |
299 | do { \ |
300 | const struct tcphdr *th = (const struct tcphdr *)skb->data; \ |
301 | struct sockaddr_in *v4 = (void *)__entry->saddr; \ |
302 | \ |
303 | v4->sin_family = AF_INET; \ |
304 | v4->sin_port = th->source; \ |
305 | v4->sin_addr.s_addr = ip_hdr(skb)->saddr; \ |
306 | v4 = (void *)__entry->daddr; \ |
307 | v4->sin_family = AF_INET; \ |
308 | v4->sin_port = th->dest; \ |
309 | v4->sin_addr.s_addr = ip_hdr(skb)->daddr; \ |
310 | } while (0) |
311 | |
312 | #if IS_ENABLED(CONFIG_IPV6) |
313 | |
314 | #define TP_STORE_ADDR_PORTS_SKB(__entry, skb) \ |
315 | do { \ |
316 | const struct iphdr *iph = ip_hdr(skb); \ |
317 | \ |
318 | if (iph->version == 6) { \ |
319 | const struct tcphdr *th = (const struct tcphdr *)skb->data; \ |
320 | struct sockaddr_in6 *v6 = (void *)__entry->saddr; \ |
321 | \ |
322 | v6->sin6_family = AF_INET6; \ |
323 | v6->sin6_port = th->source; \ |
324 | v6->sin6_addr = ipv6_hdr(skb)->saddr; \ |
325 | v6 = (void *)__entry->daddr; \ |
326 | v6->sin6_family = AF_INET6; \ |
327 | v6->sin6_port = th->dest; \ |
328 | v6->sin6_addr = ipv6_hdr(skb)->daddr; \ |
329 | } else \ |
330 | TP_STORE_ADDR_PORTS_SKB_V4(__entry, skb); \ |
331 | } while (0) |
332 | |
333 | #else |
334 | |
335 | #define TP_STORE_ADDR_PORTS_SKB(__entry, skb) \ |
336 | TP_STORE_ADDR_PORTS_SKB_V4(__entry, skb) |
337 | |
338 | #endif |
339 | |
340 | /* |
341 | * tcp event with only skb |
342 | */ |
343 | DECLARE_EVENT_CLASS(tcp_event_skb, |
344 | |
345 | TP_PROTO(const struct sk_buff *skb), |
346 | |
347 | TP_ARGS(skb), |
348 | |
349 | TP_STRUCT__entry( |
350 | __field(const void *, skbaddr) |
351 | __array(__u8, saddr, sizeof(struct sockaddr_in6)) |
352 | __array(__u8, daddr, sizeof(struct sockaddr_in6)) |
353 | ), |
354 | |
355 | TP_fast_assign( |
356 | __entry->skbaddr = skb; |
357 | |
358 | memset(__entry->saddr, 0, sizeof(struct sockaddr_in6)); |
359 | memset(__entry->daddr, 0, sizeof(struct sockaddr_in6)); |
360 | |
361 | TP_STORE_ADDR_PORTS_SKB(__entry, skb); |
362 | ), |
363 | |
364 | TP_printk("src=%pISpc dest=%pISpc" , __entry->saddr, __entry->daddr) |
365 | ); |
366 | |
367 | DEFINE_EVENT(tcp_event_skb, tcp_bad_csum, |
368 | |
369 | TP_PROTO(const struct sk_buff *skb), |
370 | |
371 | TP_ARGS(skb) |
372 | ); |
373 | |
374 | TRACE_EVENT(tcp_cong_state_set, |
375 | |
376 | TP_PROTO(struct sock *sk, const u8 ca_state), |
377 | |
378 | TP_ARGS(sk, ca_state), |
379 | |
380 | TP_STRUCT__entry( |
381 | __field(const void *, skaddr) |
382 | __field(__u16, sport) |
383 | __field(__u16, dport) |
384 | __field(__u16, family) |
385 | __array(__u8, saddr, 4) |
386 | __array(__u8, daddr, 4) |
387 | __array(__u8, saddr_v6, 16) |
388 | __array(__u8, daddr_v6, 16) |
389 | __field(__u8, cong_state) |
390 | ), |
391 | |
392 | TP_fast_assign( |
393 | struct inet_sock *inet = inet_sk(sk); |
394 | __be32 *p32; |
395 | |
396 | __entry->skaddr = sk; |
397 | |
398 | __entry->sport = ntohs(inet->inet_sport); |
399 | __entry->dport = ntohs(inet->inet_dport); |
400 | __entry->family = sk->sk_family; |
401 | |
402 | p32 = (__be32 *) __entry->saddr; |
403 | *p32 = inet->inet_saddr; |
404 | |
405 | p32 = (__be32 *) __entry->daddr; |
406 | *p32 = inet->inet_daddr; |
407 | |
408 | TP_STORE_ADDRS(__entry, inet->inet_saddr, inet->inet_daddr, |
409 | sk->sk_v6_rcv_saddr, sk->sk_v6_daddr); |
410 | |
411 | __entry->cong_state = ca_state; |
412 | ), |
413 | |
414 | TP_printk("family=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c cong_state=%u" , |
415 | show_family_name(__entry->family), |
416 | __entry->sport, __entry->dport, |
417 | __entry->saddr, __entry->daddr, |
418 | __entry->saddr_v6, __entry->daddr_v6, |
419 | __entry->cong_state) |
420 | ); |
421 | |
422 | #endif /* _TRACE_TCP_H */ |
423 | |
424 | /* This part must be outside protection */ |
425 | #include <trace/define_trace.h> |
426 | |