Commit | Line | Data |
---|---|---|
b7cdc182 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
b283666f PW |
2 | #undef TRACE_SYSTEM |
3 | #define TRACE_SYSTEM net | |
4 | ||
3bc29f0a MD |
5 | #if !defined(LTTNG_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ) |
6 | #define LTTNG_TRACE_NET_H | |
b283666f | 7 | |
3b4aafcb | 8 | #include <lttng/tracepoint-event.h> |
b283666f PW |
9 | #include <linux/skbuff.h> |
10 | #include <linux/netdevice.h> | |
11 | #include <linux/ip.h> | |
e5990fd4 GB |
12 | #include <linux/ipv6.h> |
13 | #include <linux/tcp.h> | |
f6dd81c5 FW |
14 | #include <linux/udp.h> |
15 | #include <linux/icmp.h> | |
4a7363f7 | 16 | #include <linux/version.h> |
2df37e95 | 17 | #include <lttng/endian.h> |
e5990fd4 GB |
18 | #include <net/sock.h> |
19 | ||
20 | #ifndef ONCE_LTTNG_NET_H | |
21 | #define ONCE_LTTNG_NET_H | |
22 | ||
23 | static inline unsigned char __has_network_hdr(struct sk_buff *skb) | |
24 | { | |
25 | /* | |
aa900596 MD |
26 | * If the header is not set yet, the network header will point |
27 | * to the head. | |
e5990fd4 GB |
28 | */ |
29 | return skb_network_header(skb) != skb->head; | |
30 | } | |
31 | ||
32 | static struct lttng_event_field emptyfields[] = { | |
33 | }; | |
34 | ||
9cf9736a GB |
35 | /* Structures for transport headers. */ |
36 | ||
37 | static struct lttng_event_field tcpfields[] = { | |
38 | [0] = { | |
39 | .name = "source_port", | |
aa900596 MD |
40 | .type = __type_integer(uint16_t, 0, 0, 0, |
41 | __BIG_ENDIAN, 10, none), | |
9cf9736a GB |
42 | }, |
43 | [1] = { | |
44 | .name = "dest_port", | |
aa900596 MD |
45 | .type = __type_integer(uint16_t, 0, 0, 0, |
46 | __BIG_ENDIAN, 10, none), | |
9cf9736a GB |
47 | }, |
48 | [2] = { | |
49 | .name = "seq", | |
aa900596 MD |
50 | .type = __type_integer(uint32_t, 0, 0, 0, |
51 | __BIG_ENDIAN, 10, none), | |
9cf9736a GB |
52 | }, |
53 | [3] = { | |
54 | .name = "ack_seq", | |
aa900596 MD |
55 | .type = __type_integer(uint32_t, 0, 0, 0, |
56 | __BIG_ENDIAN, 10, none), | |
9cf9736a GB |
57 | }, |
58 | [4] = { | |
59 | .name = "data_offset", | |
aa900596 MD |
60 | .type = __type_integer(uint8_t, 4, 4, 0, |
61 | __BIG_ENDIAN, 10, none), | |
9cf9736a GB |
62 | }, |
63 | [5] = { | |
64 | .name = "reserved", | |
aa900596 MD |
65 | .type = __type_integer(uint8_t, 3, 1, 0, |
66 | __BIG_ENDIAN, 10, none), | |
9cf9736a GB |
67 | }, |
68 | [6] = { | |
69 | .name = "flags", | |
aa900596 MD |
70 | .type = __type_integer(uint8_t, 9, 1, 0, |
71 | __BIG_ENDIAN, 16, none), | |
9cf9736a GB |
72 | }, |
73 | [7] = { | |
74 | .name = "window_size", | |
aa900596 MD |
75 | .type = __type_integer(uint16_t, 0, 0, 0, |
76 | __BIG_ENDIAN, 10, none), | |
9cf9736a GB |
77 | }, |
78 | [8] = { | |
79 | .name = "checksum", | |
aa900596 MD |
80 | .type = __type_integer(uint16_t, 0, 0, 0, |
81 | __BIG_ENDIAN, 16, none), | |
9cf9736a GB |
82 | }, |
83 | [9] = { | |
84 | .name = "urg_ptr", | |
aa900596 MD |
85 | .type = __type_integer(uint16_t, 0, 0, 0, |
86 | __BIG_ENDIAN, 10, none), | |
9cf9736a GB |
87 | }, |
88 | }; | |
89 | ||
f6dd81c5 FW |
90 | static struct lttng_event_field udpfields[] = { |
91 | [0] = { | |
92 | .name = "source_port", | |
93 | .type = __type_integer(uint16_t, 0, 0, 0, | |
94 | __BIG_ENDIAN, 10, none), | |
95 | }, | |
96 | [1] = { | |
97 | .name = "dest_port", | |
98 | .type = __type_integer(uint16_t, 0, 0, 0, | |
99 | __BIG_ENDIAN, 10, none), | |
100 | }, | |
101 | [2] = { | |
102 | .name = "len", | |
103 | .type = __type_integer(uint16_t, 0, 0, 0, | |
104 | __BIG_ENDIAN, 10, none), | |
105 | }, | |
106 | [3] = { | |
107 | .name = "check", | |
108 | .type = __type_integer(uint16_t, 0, 0, 0, | |
109 | __BIG_ENDIAN, 10, none), | |
110 | }, | |
111 | }; | |
112 | ||
113 | static struct lttng_event_field icmpfields[] = { | |
114 | [0] = { | |
115 | .name = "type", | |
116 | .type = __type_integer(uint8_t, 0, 0, 0, | |
117 | __BIG_ENDIAN, 10, none), | |
118 | }, | |
119 | [1] = { | |
120 | .name = "code", | |
121 | .type = __type_integer(uint8_t, 0, 0, 0, | |
122 | __BIG_ENDIAN, 10, none), | |
123 | }, | |
124 | [2] = { | |
125 | .name = "checksum", | |
126 | .type = __type_integer(uint16_t, 0, 0, 0, | |
127 | __BIG_ENDIAN, 10, none), | |
128 | }, | |
129 | [3] = { | |
130 | .name = "gateway", | |
131 | .type = __type_integer(uint32_t, 0, 0, 0, | |
132 | __BIG_ENDIAN, 10, none), | |
133 | }, | |
134 | }; | |
135 | ||
136 | ||
9cf9736a GB |
137 | static struct lttng_event_field transport_fields[] = { |
138 | [0] = { | |
139 | .name = "unknown", | |
140 | .type = { | |
ceabb767 MD |
141 | .atype = atype_struct_nestable, |
142 | .u.struct_nestable.nr_fields = ARRAY_SIZE(emptyfields), | |
143 | .u.struct_nestable.fields = emptyfields, | |
144 | .u.struct_nestable.alignment = 0, | |
9cf9736a | 145 | }, |
ceabb767 | 146 | .nofilter = 1, |
9cf9736a GB |
147 | }, |
148 | [1] = { | |
149 | .name = "tcp", | |
150 | .type = { | |
ceabb767 MD |
151 | .atype = atype_struct_nestable, |
152 | .u.struct_nestable.nr_fields = ARRAY_SIZE(tcpfields), | |
153 | .u.struct_nestable.fields = tcpfields, | |
154 | .u.struct_nestable.alignment = 0, | |
9cf9736a | 155 | }, |
ceabb767 | 156 | .nofilter = 1, |
9cf9736a | 157 | }, |
f6dd81c5 FW |
158 | [2] = { |
159 | .name = "udp", | |
160 | .type = { | |
ceabb767 MD |
161 | .atype = atype_struct_nestable, |
162 | .u.struct_nestable.nr_fields = ARRAY_SIZE(udpfields), | |
163 | .u.struct_nestable.fields = udpfields, | |
164 | .u.struct_nestable.alignment = 0, | |
f6dd81c5 | 165 | }, |
ceabb767 | 166 | .nofilter = 1, |
f6dd81c5 FW |
167 | }, |
168 | [3] = { | |
169 | .name = "icmp", | |
170 | .type = { | |
ceabb767 MD |
171 | .atype = atype_struct_nestable, |
172 | .u.struct_nestable.nr_fields = ARRAY_SIZE(icmpfields), | |
173 | .u.struct_nestable.fields = icmpfields, | |
174 | .u.struct_nestable.alignment = 0, | |
f6dd81c5 | 175 | }, |
ceabb767 | 176 | .nofilter = 1, |
f6dd81c5 | 177 | }, |
9cf9736a GB |
178 | }; |
179 | ||
180 | enum transport_header_types { | |
0910ab71 MD |
181 | TH_NONE = 0, |
182 | TH_TCP = 1, | |
f6dd81c5 FW |
183 | TH_UDP = 2, |
184 | TH_ICMP = 3, | |
9cf9736a GB |
185 | }; |
186 | ||
f6dd81c5 FW |
187 | static inline enum transport_header_types __get_transport_header_type_ip(struct sk_buff *skb) |
188 | { | |
189 | switch (ip_hdr(skb)->protocol) { | |
190 | case IPPROTO_TCP: | |
191 | return TH_TCP; | |
192 | case IPPROTO_UDP: | |
193 | return TH_UDP; | |
194 | case IPPROTO_ICMP: | |
195 | return TH_ICMP; | |
196 | } | |
197 | return TH_NONE; | |
198 | } | |
199 | ||
200 | static inline enum transport_header_types __get_transport_header_type_ipv6(struct sk_buff *skb) | |
201 | { | |
202 | switch (ipv6_hdr(skb)->nexthdr) { | |
203 | case IPPROTO_TCP: | |
204 | return TH_TCP; | |
205 | case IPPROTO_UDP: | |
206 | return TH_UDP; | |
207 | case IPPROTO_ICMP: | |
208 | return TH_ICMP; | |
209 | } | |
210 | return TH_NONE; | |
211 | } | |
212 | ||
0910ab71 | 213 | static inline enum transport_header_types __get_transport_header_type(struct sk_buff *skb) |
9cf9736a GB |
214 | { |
215 | if (__has_network_hdr(skb)) { | |
216 | /* | |
aa900596 MD |
217 | * When both transport and network headers are set, |
218 | * transport header is greater than network header, | |
219 | * otherwise it points to head. | |
9cf9736a GB |
220 | */ |
221 | if (skb->transport_header > skb->network_header) { | |
222 | /* | |
aa900596 MD |
223 | * Get the transport protocol from the network |
224 | * header's data. This method works both for | |
225 | * sent and received packets. | |
9cf9736a | 226 | */ |
f6dd81c5 FW |
227 | if (skb->protocol == htons(ETH_P_IP)) { |
228 | return __get_transport_header_type_ip(skb); | |
229 | } else if(skb->protocol == htons(ETH_P_IPV6)) { | |
230 | return __get_transport_header_type_ipv6(skb); | |
231 | } | |
9cf9736a | 232 | } |
f6dd81c5 | 233 | /* Fallthrough for other cases where header is not recognized. */ |
9cf9736a GB |
234 | } |
235 | return TH_NONE; | |
236 | } | |
237 | ||
7299e758 MD |
238 | static struct lttng_enum_entry proto_transport_enum_entries[] = { |
239 | [0] = { | |
240 | .start = { .value = 0, .signedness = 0, }, | |
f6dd81c5 | 241 | .end = { .value = IPPROTO_ICMP - 1, .signedness = 0, }, |
7299e758 MD |
242 | .string = "_unknown", |
243 | }, | |
244 | [1] = { | |
f6dd81c5 FW |
245 | .start = { .value = IPPROTO_ICMP, .signedness = 0, }, |
246 | .end = { .value = IPPROTO_ICMP, .signedness = 0, }, | |
247 | .string = "_icmp", | |
248 | }, | |
249 | [2] = { | |
250 | .start = { .value = IPPROTO_ICMP + 1, .signedness = 0, }, | |
251 | .end = { .value = IPPROTO_TCP - 1, .signedness = 0, }, | |
252 | .string = "_unknown", | |
253 | }, | |
254 | [3] = { | |
7299e758 MD |
255 | .start = { .value = IPPROTO_TCP, .signedness = 0, }, |
256 | .end = { .value = IPPROTO_TCP, .signedness = 0, }, | |
257 | .string = "_tcp", | |
258 | }, | |
f6dd81c5 | 259 | [4] = { |
7299e758 | 260 | .start = { .value = IPPROTO_TCP + 1, .signedness = 0, }, |
f6dd81c5 FW |
261 | .end = { .value = IPPROTO_UDP - 1, .signedness = 0, }, |
262 | .string = "_unknown", | |
263 | }, | |
264 | [5] = { | |
265 | .start = { .value = IPPROTO_UDP, .signedness = 0, }, | |
266 | .end = { .value = IPPROTO_UDP, .signedness = 0, }, | |
267 | .string = "_udp", | |
268 | }, | |
269 | [6] = { | |
270 | .start = { .value = IPPROTO_UDP + 1, .signedness = 0, }, | |
7299e758 MD |
271 | .end = { .value = 255, .signedness = 0, }, |
272 | .string = "_unknown", | |
273 | }, | |
274 | }; | |
275 | ||
276 | static const struct lttng_enum_desc proto_transport_header_type = { | |
277 | .name = "proto_transport_header_type", | |
278 | .entries = proto_transport_enum_entries, | |
279 | .nr_entries = ARRAY_SIZE(proto_transport_enum_entries), | |
280 | }; | |
281 | ||
9cf9736a GB |
282 | static struct lttng_enum_entry transport_enum_entries[] = { |
283 | [0] = { | |
0910ab71 MD |
284 | .start = { .value = TH_NONE, .signedness = 0, }, |
285 | .end = { .value = TH_NONE, .signedness = 0, }, | |
9cf9736a GB |
286 | .string = "_unknown", |
287 | }, | |
288 | [1] = { | |
0910ab71 MD |
289 | .start = { .value = TH_TCP, .signedness = 0, }, |
290 | .end = { .value = TH_TCP, .signedness = 0, }, | |
9cf9736a GB |
291 | .string = "_tcp", |
292 | }, | |
f6dd81c5 FW |
293 | [2] = { |
294 | .start = { .value = TH_UDP, .signedness = 0, }, | |
295 | .end = { .value = TH_UDP, .signedness = 0, }, | |
296 | .string = "_udp", | |
297 | }, | |
298 | [3] = { | |
299 | .start = { .value = TH_ICMP, .signedness = 0, }, | |
300 | .end = { .value = TH_ICMP, .signedness = 0, }, | |
301 | .string = "_icmp", | |
302 | }, | |
9cf9736a GB |
303 | }; |
304 | ||
305 | static const struct lttng_enum_desc transport_header_type = { | |
306 | .name = "transport_header_type", | |
307 | .entries = transport_enum_entries, | |
308 | .nr_entries = ARRAY_SIZE(transport_enum_entries), | |
309 | }; | |
310 | ||
e5990fd4 GB |
311 | /* Structures for network headers. */ |
312 | ||
313 | static struct lttng_event_field ipv4fields[] = { | |
314 | [0] = { | |
315 | .name = "version", | |
aa900596 MD |
316 | .type = __type_integer(uint8_t, 4, 4, 0, |
317 | __BIG_ENDIAN, 10, none), | |
e5990fd4 GB |
318 | }, |
319 | [1] = { | |
320 | .name = "ihl", | |
aa900596 MD |
321 | .type = __type_integer(uint8_t, 4, 4, 0, |
322 | __BIG_ENDIAN, 10, none), | |
e5990fd4 GB |
323 | }, |
324 | [2] = { | |
325 | .name = "tos", | |
aa900596 MD |
326 | .type = __type_integer(uint8_t, 0, 0, 0, |
327 | __BIG_ENDIAN, 10, none), | |
e5990fd4 GB |
328 | }, |
329 | [3] = { | |
330 | .name = "tot_len", | |
aa900596 MD |
331 | .type = __type_integer(uint16_t, 0, 0, 0, |
332 | __BIG_ENDIAN, 10, none), | |
e5990fd4 GB |
333 | }, |
334 | [4] = { | |
335 | .name = "id", | |
aa900596 MD |
336 | .type = __type_integer(uint16_t, 0, 0, 0, |
337 | __BIG_ENDIAN, 16, none), | |
e5990fd4 GB |
338 | }, |
339 | [5] = { | |
340 | .name = "frag_off", | |
aa900596 MD |
341 | .type = __type_integer(uint16_t, 0, 0, 0, |
342 | __BIG_ENDIAN, 10, none), | |
e5990fd4 GB |
343 | }, |
344 | [6] = { | |
345 | .name = "ttl", | |
aa900596 MD |
346 | .type = __type_integer(uint8_t, 0, 0, 0, |
347 | __BIG_ENDIAN, 10, none), | |
e5990fd4 GB |
348 | }, |
349 | [7] = { | |
350 | .name = "protocol", | |
9cf9736a | 351 | .type = { |
ceabb767 MD |
352 | .atype = atype_enum_nestable, |
353 | .u.enum_nestable.desc = | |
7299e758 | 354 | &proto_transport_header_type, |
ceabb767 MD |
355 | .u.enum_nestable.container_type = |
356 | __LTTNG_COMPOUND_LITERAL(struct lttng_type, | |
357 | __type_integer(uint8_t, 0, 0, -1, | |
358 | __BIG_ENDIAN, 10, none)), | |
9cf9736a | 359 | }, |
e5990fd4 GB |
360 | }, |
361 | [8] = { | |
362 | .name = "checksum", | |
aa900596 MD |
363 | .type = __type_integer(uint16_t, 0, 0, 0, |
364 | __BIG_ENDIAN, 16, none), | |
e5990fd4 GB |
365 | }, |
366 | [9] = { | |
367 | .name = "saddr", | |
368 | .type = { | |
ceabb767 MD |
369 | .atype = atype_array_nestable, |
370 | .u.array_nestable.elem_type = | |
371 | __LTTNG_COMPOUND_LITERAL(struct lttng_type, | |
372 | __type_integer(uint8_t, 0, 0, 0, | |
373 | __BIG_ENDIAN, 10, none)), | |
374 | .u.array_nestable.length = 4, | |
375 | .u.array_nestable.alignment = lttng_alignof(uint8_t), | |
e5990fd4 GB |
376 | }, |
377 | }, | |
378 | [10] = { | |
379 | .name = "daddr", | |
380 | .type = { | |
ceabb767 MD |
381 | .atype = atype_array_nestable, |
382 | .u.array_nestable.elem_type = | |
383 | __LTTNG_COMPOUND_LITERAL(struct lttng_type, | |
384 | __type_integer(uint8_t, 0, 0, 0, | |
385 | __BIG_ENDIAN, 10, none)), | |
386 | .u.array_nestable.length = 4, | |
387 | .u.array_nestable.alignment = lttng_alignof(uint8_t), | |
e5990fd4 GB |
388 | }, |
389 | }, | |
9cf9736a | 390 | [11] = { |
0910ab71 MD |
391 | .name = "transport_header_type", |
392 | .type = { | |
ceabb767 MD |
393 | .atype = atype_enum_nestable, |
394 | .u.enum_nestable.desc = &transport_header_type, | |
395 | .u.enum_nestable.container_type = | |
396 | __LTTNG_COMPOUND_LITERAL(struct lttng_type, | |
397 | __type_integer(uint8_t, 0, 0, -1, | |
398 | __BYTE_ORDER, 10, none)), | |
0910ab71 MD |
399 | }, |
400 | }, | |
401 | [12] = { | |
9cf9736a GB |
402 | .name = "transport_header", |
403 | .type = { | |
ceabb767 MD |
404 | .atype = atype_variant_nestable, |
405 | .u.variant_nestable.tag_name = "transport_header_type", | |
406 | .u.variant_nestable.choices = transport_fields, | |
407 | .u.variant_nestable.nr_choices = ARRAY_SIZE(transport_fields), | |
408 | .u.variant_nestable.alignment = 0, | |
9cf9736a GB |
409 | }, |
410 | }, | |
e5990fd4 GB |
411 | }; |
412 | ||
413 | static struct lttng_event_field ipv6fields[] = { | |
414 | [0] = { | |
415 | .name = "version", | |
aa900596 MD |
416 | .type = __type_integer(uint8_t, 4, 4, 0, |
417 | __BIG_ENDIAN, 10, none), | |
e5990fd4 GB |
418 | }, |
419 | [1] = { | |
420 | .name = "prio", | |
aa900596 MD |
421 | .type = __type_integer(uint8_t, 4, 4, 0, |
422 | __BIG_ENDIAN, 10, none), | |
e5990fd4 GB |
423 | }, |
424 | [2] = { | |
425 | .name = "flow_lbl", | |
426 | .type = { | |
ceabb767 MD |
427 | .atype = atype_array_nestable, |
428 | .u.array_nestable.elem_type = | |
429 | __LTTNG_COMPOUND_LITERAL(struct lttng_type, | |
430 | __type_integer(uint8_t, 0, 0, 0, | |
431 | __BIG_ENDIAN, 16, none)), | |
432 | .u.array_nestable.length = 3, | |
433 | .u.array_nestable.alignment = lttng_alignof(uint8_t), | |
e5990fd4 GB |
434 | }, |
435 | }, | |
436 | [3] = { | |
437 | .name = "payload_len", | |
aa900596 MD |
438 | .type = __type_integer(uint16_t, 0, 0, 0, |
439 | __BIG_ENDIAN, 10, none), | |
e5990fd4 GB |
440 | }, |
441 | [4] = { | |
442 | .name = "nexthdr", | |
9cf9736a | 443 | .type = { |
ceabb767 MD |
444 | .atype = atype_enum_nestable, |
445 | .u.enum_nestable.desc = | |
7299e758 | 446 | &proto_transport_header_type, |
ceabb767 MD |
447 | .u.enum_nestable.container_type = |
448 | __LTTNG_COMPOUND_LITERAL(struct lttng_type, | |
449 | __type_integer(uint8_t, 0, 0, -1, | |
450 | __BIG_ENDIAN, 10, none)), | |
9cf9736a | 451 | }, |
e5990fd4 GB |
452 | }, |
453 | [5] = { | |
454 | .name = "hop_limit", | |
aa900596 MD |
455 | .type = __type_integer(uint8_t, 0, 0, 0, |
456 | __BIG_ENDIAN, 10, none), | |
e5990fd4 GB |
457 | }, |
458 | [6] = { | |
459 | .name = "saddr", | |
460 | .type = { | |
ceabb767 MD |
461 | .atype = atype_array_nestable, |
462 | .u.array_nestable.elem_type = | |
463 | __LTTNG_COMPOUND_LITERAL(struct lttng_type, | |
464 | __type_integer(uint16_t, 0, 0, 0, | |
465 | __BIG_ENDIAN, 16, none)), | |
466 | .u.array_nestable.length = 8, | |
467 | .u.array_nestable.alignment = lttng_alignof(uint16_t), | |
e5990fd4 GB |
468 | }, |
469 | }, | |
470 | [7] = { | |
471 | .name = "daddr", | |
472 | .type = { | |
ceabb767 MD |
473 | .atype = atype_array_nestable, |
474 | .u.array_nestable.elem_type = | |
475 | __LTTNG_COMPOUND_LITERAL(struct lttng_type, | |
476 | __type_integer(uint16_t, 0, 0, 0, | |
477 | __BIG_ENDIAN, 16, none)), | |
478 | .u.array_nestable.length = 8, | |
479 | .u.array_nestable.alignment = lttng_alignof(uint16_t), | |
e5990fd4 GB |
480 | }, |
481 | }, | |
9cf9736a | 482 | [8] = { |
0910ab71 MD |
483 | .name = "transport_header_type", |
484 | .type = { | |
ceabb767 MD |
485 | .atype = atype_enum_nestable, |
486 | .u.enum_nestable.desc = &transport_header_type, | |
487 | .u.enum_nestable.container_type = | |
488 | __LTTNG_COMPOUND_LITERAL(struct lttng_type, | |
489 | __type_integer(uint8_t, 0, 0, -1, | |
490 | __BYTE_ORDER, 10, none)), | |
0910ab71 MD |
491 | }, |
492 | }, | |
493 | [9] = { | |
9cf9736a GB |
494 | .name = "transport_header", |
495 | .type = { | |
ceabb767 MD |
496 | .atype = atype_variant_nestable, |
497 | .u.variant_nestable.tag_name = "transport_header_type", | |
498 | .u.variant_nestable.choices = transport_fields, | |
499 | .u.variant_nestable.nr_choices = ARRAY_SIZE(transport_fields), | |
500 | .u.variant_nestable.alignment = 0, | |
9cf9736a GB |
501 | }, |
502 | }, | |
e5990fd4 GB |
503 | }; |
504 | ||
505 | static struct lttng_event_field network_fields[] = { | |
506 | [0] = { | |
507 | .name = "unknown", | |
508 | .type = { | |
ceabb767 MD |
509 | .atype = atype_struct_nestable, |
510 | .u.struct_nestable.nr_fields = 0, | |
511 | .u.struct_nestable.fields = emptyfields, | |
512 | .u.struct_nestable.alignment = 0, | |
e5990fd4 GB |
513 | }, |
514 | }, | |
515 | [1] = { | |
516 | .name = "ipv4", | |
517 | .type = { | |
ceabb767 MD |
518 | .atype = atype_struct_nestable, |
519 | .u.struct_nestable.nr_fields = ARRAY_SIZE(ipv4fields), | |
520 | .u.struct_nestable.fields = ipv4fields, | |
521 | .u.struct_nestable.alignment = 0, | |
e5990fd4 GB |
522 | }, |
523 | }, | |
524 | [2] = { | |
525 | .name = "ipv6", | |
526 | .type = { | |
ceabb767 MD |
527 | .atype = atype_struct_nestable, |
528 | .u.struct_nestable.nr_fields = ARRAY_SIZE(ipv6fields), | |
529 | .u.struct_nestable.fields = ipv6fields, | |
530 | .u.struct_nestable.alignment = 0, | |
e5990fd4 GB |
531 | }, |
532 | }, | |
533 | }; | |
534 | ||
535 | enum network_header_types { | |
536 | NH_NONE, | |
537 | NH_IPV4, | |
538 | NH_IPV6, | |
539 | }; | |
540 | ||
541 | static inline unsigned char __get_network_header_type(struct sk_buff *skb) | |
542 | { | |
543 | if (__has_network_hdr(skb)) { | |
544 | if (skb->protocol == htons(ETH_P_IPV6)) | |
545 | return NH_IPV6; | |
546 | else if (skb->protocol == htons(ETH_P_IP)) | |
547 | return NH_IPV4; | |
548 | /* Fallthrough for other header types. */ | |
549 | } | |
550 | return NH_NONE; | |
551 | } | |
552 | ||
553 | #endif | |
554 | ||
555 | LTTNG_TRACEPOINT_ENUM(net_network_header, | |
556 | TP_ENUM_VALUES( | |
557 | ctf_enum_value("_unknown", NH_NONE) | |
558 | ctf_enum_value("_ipv4", NH_IPV4) | |
559 | ctf_enum_value("_ipv6", NH_IPV6) | |
560 | ) | |
561 | ) | |
b283666f | 562 | |
3bc29f0a | 563 | LTTNG_TRACEPOINT_EVENT(net_dev_xmit, |
b283666f PW |
564 | |
565 | TP_PROTO(struct sk_buff *skb, | |
566 | int rc, | |
567 | struct net_device *dev, | |
568 | unsigned int skb_len), | |
569 | ||
570 | TP_ARGS(skb, rc, dev, skb_len), | |
571 | ||
f127e61e | 572 | TP_FIELDS( |
fa91fcac | 573 | ctf_integer_hex(void *, skbaddr, skb) |
f127e61e | 574 | ctf_integer(int, rc, rc) |
974c0969 | 575 | ctf_integer(unsigned int, len, skb_len) |
f127e61e | 576 | ctf_string(name, dev->name) |
f127e61e | 577 | ) |
b283666f PW |
578 | ) |
579 | ||
3bc29f0a | 580 | LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template, |
b283666f PW |
581 | |
582 | TP_PROTO(struct sk_buff *skb), | |
583 | ||
584 | TP_ARGS(skb), | |
585 | ||
f127e61e | 586 | TP_FIELDS( |
fa91fcac | 587 | ctf_integer_hex(void *, skbaddr, skb) |
f127e61e MD |
588 | ctf_integer(unsigned int, len, skb->len) |
589 | ctf_string(name, skb->dev->name) | |
e5990fd4 GB |
590 | ctf_enum(net_network_header, unsigned char, |
591 | network_header_type, __get_network_header_type(skb)) | |
592 | ctf_custom_field( | |
593 | ctf_custom_type( | |
ceabb767 MD |
594 | { |
595 | .atype = atype_variant_nestable, | |
596 | .u.variant_nestable.tag_name = "network_header_type", | |
597 | .u.variant_nestable.choices = network_fields, | |
598 | .u.variant_nestable.nr_choices = | |
599 | ARRAY_SIZE(network_fields), | |
600 | .u.variant_nestable.alignment = 0, | |
601 | } | |
e5990fd4 GB |
602 | ), |
603 | network_header, | |
604 | ctf_custom_code( | |
0910ab71 MD |
605 | bool has_network_header = false; |
606 | ||
aa900596 | 607 | /* Copy the network header. */ |
e5990fd4 GB |
608 | switch (__get_network_header_type(skb)) { |
609 | case NH_IPV4: { | |
610 | ctf_align(uint16_t) | |
611 | ctf_array_type(uint8_t, ip_hdr(skb), | |
612 | sizeof(struct iphdr)) | |
0910ab71 | 613 | has_network_header = true; |
e5990fd4 GB |
614 | break; |
615 | } | |
616 | case NH_IPV6: { | |
617 | ctf_align(uint16_t) | |
618 | ctf_array_type(uint8_t, ipv6_hdr(skb), | |
619 | sizeof(struct ipv6hdr)) | |
0910ab71 | 620 | has_network_header = true; |
e5990fd4 GB |
621 | break; |
622 | } | |
623 | default: | |
aa900596 MD |
624 | /* |
625 | * For any other network header | |
626 | * type, there is nothing to do. | |
627 | */ | |
e5990fd4 GB |
628 | break; |
629 | } | |
9cf9736a | 630 | |
0910ab71 MD |
631 | if (has_network_header) { |
632 | enum transport_header_types th_type = | |
633 | __get_transport_header_type(skb); | |
634 | ||
635 | /* Transport header type field. */ | |
636 | ctf_integer_type(unsigned char, th_type) | |
637 | ||
638 | /* Copy the transport header. */ | |
f6dd81c5 FW |
639 | switch (th_type) { |
640 | case TH_TCP: { | |
0910ab71 MD |
641 | ctf_align(uint32_t) |
642 | ctf_array_type(uint8_t, tcp_hdr(skb), | |
643 | sizeof(struct tcphdr)) | |
f6dd81c5 FW |
644 | break; |
645 | } | |
646 | case TH_UDP: { | |
647 | ctf_align(uint32_t) | |
648 | ctf_array_type(uint8_t, udp_hdr(skb), | |
649 | sizeof(struct udphdr)) | |
650 | break; | |
651 | } | |
652 | case TH_ICMP: { | |
653 | ctf_align(uint32_t) | |
654 | ctf_array_type(uint8_t, icmp_hdr(skb), | |
655 | sizeof(struct icmphdr)) | |
656 | break; | |
657 | } | |
658 | default: | |
659 | /* | |
660 | * For any other transport header type, | |
661 | * there is nothing to do. | |
662 | */ | |
663 | break; | |
0910ab71 | 664 | } |
9cf9736a | 665 | } |
e5990fd4 GB |
666 | ) |
667 | ) | |
f127e61e | 668 | ) |
b283666f PW |
669 | ) |
670 | ||
3bc29f0a | 671 | LTTNG_TRACEPOINT_EVENT_INSTANCE(net_dev_template, net_dev_queue, |
b283666f PW |
672 | |
673 | TP_PROTO(struct sk_buff *skb), | |
674 | ||
675 | TP_ARGS(skb) | |
676 | ) | |
677 | ||
b7f5408a MD |
678 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template, |
679 | ||
680 | netif_receive_skb, | |
681 | ||
682 | net_if_receive_skb, | |
b283666f PW |
683 | |
684 | TP_PROTO(struct sk_buff *skb), | |
685 | ||
686 | TP_ARGS(skb) | |
687 | ) | |
688 | ||
b7f5408a MD |
689 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template, |
690 | ||
691 | netif_rx, | |
692 | ||
693 | net_if_rx, | |
b283666f PW |
694 | |
695 | TP_PROTO(struct sk_buff *skb), | |
696 | ||
697 | TP_ARGS(skb) | |
698 | ) | |
e9d818b9 GB |
699 | |
700 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) | |
701 | ||
702 | /* Trace events for the receive entry points */ | |
703 | LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_receive_entry_template, | |
704 | ||
705 | TP_PROTO(const struct sk_buff *skb), | |
706 | ||
707 | TP_ARGS(skb), | |
708 | ||
709 | TP_FIELDS( | |
710 | ctf_integer_hex(const void *, skbaddr, skb) | |
711 | ) | |
712 | ) | |
713 | ||
714 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template, | |
715 | ||
716 | napi_gro_frags_entry, | |
717 | ||
718 | net_napi_gro_frags_entry, | |
719 | ||
720 | TP_PROTO(const struct sk_buff *skb), | |
721 | ||
722 | TP_ARGS(skb) | |
723 | ) | |
724 | ||
725 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template, | |
726 | ||
727 | napi_gro_receive_entry, | |
728 | ||
729 | net_napi_gro_receive_entry, | |
730 | ||
731 | TP_PROTO(const struct sk_buff *skb), | |
732 | ||
733 | TP_ARGS(skb) | |
734 | ) | |
735 | ||
736 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template, | |
737 | ||
738 | netif_receive_skb_entry, | |
739 | ||
740 | net_if_receive_skb_entry, | |
741 | ||
742 | TP_PROTO(const struct sk_buff *skb), | |
743 | ||
744 | TP_ARGS(skb) | |
745 | ) | |
746 | ||
747 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template, | |
748 | ||
749 | netif_rx_entry, | |
750 | ||
751 | net_if_rx_entry, | |
752 | ||
753 | TP_PROTO(const struct sk_buff *skb), | |
754 | ||
755 | TP_ARGS(skb) | |
756 | ) | |
757 | ||
758 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template, | |
759 | ||
760 | netif_rx_ni_entry, | |
761 | ||
762 | net_if_rx_ni_entry, | |
763 | ||
764 | TP_PROTO(const struct sk_buff *skb), | |
765 | ||
766 | TP_ARGS(skb) | |
767 | ) | |
768 | ||
769 | #endif /* kernel > 3.14 */ | |
770 | ||
771 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,0)) | |
772 | ||
773 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template, | |
774 | ||
775 | netif_receive_skb_list_entry, | |
776 | ||
777 | net_if_receive_skb_list_entry, | |
778 | ||
779 | TP_PROTO(const struct sk_buff *skb), | |
780 | ||
781 | TP_ARGS(skb) | |
782 | ) | |
783 | ||
784 | #endif /* kernel > 4.19 */ | |
785 | ||
786 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)) | |
787 | ||
788 | /* Trace events for the receive exit points */ | |
789 | LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_receive_exit_template, | |
790 | ||
791 | TP_PROTO(int ret), | |
792 | ||
793 | TP_ARGS(ret), | |
794 | ||
795 | TP_FIELDS( | |
796 | ctf_integer(int, ret, ret) | |
797 | ) | |
798 | ) | |
799 | ||
800 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template, | |
801 | ||
802 | napi_gro_frags_exit, | |
803 | ||
804 | net_napi_gro_frags_exit, | |
805 | ||
806 | TP_PROTO(int ret), | |
807 | ||
808 | TP_ARGS(ret) | |
809 | ) | |
810 | ||
811 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template, | |
812 | ||
813 | napi_gro_receive_exit, | |
814 | ||
815 | net_napi_gro_receive_exit, | |
816 | ||
817 | TP_PROTO(int ret), | |
818 | ||
819 | TP_ARGS(ret) | |
820 | ) | |
821 | ||
822 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template, | |
823 | ||
824 | netif_receive_skb_exit, | |
825 | ||
826 | net_if_receive_skb_exit, | |
827 | ||
828 | TP_PROTO(int ret), | |
829 | ||
830 | TP_ARGS(ret) | |
831 | ) | |
832 | ||
833 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template, | |
834 | ||
835 | netif_rx_exit, | |
836 | ||
837 | net_if_rx_exit, | |
838 | ||
839 | TP_PROTO(int ret), | |
840 | ||
841 | TP_ARGS(ret) | |
842 | ) | |
843 | ||
844 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template, | |
845 | ||
846 | netif_rx_ni_exit, | |
847 | ||
848 | net_if_rx_ni_exit, | |
849 | ||
850 | TP_PROTO(int ret), | |
851 | ||
852 | TP_ARGS(ret) | |
853 | ) | |
854 | ||
855 | LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template, | |
856 | ||
857 | netif_receive_skb_list_exit, | |
858 | ||
859 | net_if_receive_skb_list_exit, | |
860 | ||
861 | TP_PROTO(int ret), | |
862 | ||
863 | TP_ARGS(ret) | |
864 | ) | |
865 | ||
866 | #endif /* kernel > 5.0.0 */ | |
867 | ||
3bc29f0a | 868 | #endif /* LTTNG_TRACE_NET_H */ |
b283666f PW |
869 | |
870 | /* This part must be outside protection */ | |
3b4aafcb | 871 | #include <lttng/define_trace.h> |