1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #define TRACE_SYSTEM net
5 #if !defined(LTTNG_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ)
6 #define LTTNG_TRACE_NET_H
8 #include <probes/lttng-tracepoint-event.h>
9 #include <linux/skbuff.h>
10 #include <linux/netdevice.h>
12 #include <linux/ipv6.h>
13 #include <linux/tcp.h>
14 #include <linux/udp.h>
15 #include <linux/icmp.h>
16 #include <linux/version.h>
17 #include <lttng-endian.h>
20 #ifndef ONCE_LTTNG_NET_H
21 #define ONCE_LTTNG_NET_H
23 static inline unsigned char __has_network_hdr(struct sk_buff
*skb
)
26 * If the header is not set yet, the network header will point
29 return skb_network_header(skb
) != skb
->head
;
32 static struct lttng_event_field emptyfields
[] = {
35 /* Structures for transport headers. */
37 static struct lttng_event_field tcpfields
[] = {
39 .name
= "source_port",
40 .type
= __type_integer(uint16_t, 0, 0, 0,
41 __BIG_ENDIAN
, 10, none
),
45 .type
= __type_integer(uint16_t, 0, 0, 0,
46 __BIG_ENDIAN
, 10, none
),
50 .type
= __type_integer(uint32_t, 0, 0, 0,
51 __BIG_ENDIAN
, 10, none
),
55 .type
= __type_integer(uint32_t, 0, 0, 0,
56 __BIG_ENDIAN
, 10, none
),
59 .name
= "data_offset",
60 .type
= __type_integer(uint8_t, 4, 4, 0,
61 __BIG_ENDIAN
, 10, none
),
65 .type
= __type_integer(uint8_t, 3, 1, 0,
66 __BIG_ENDIAN
, 10, none
),
70 .type
= __type_integer(uint8_t, 9, 1, 0,
71 __BIG_ENDIAN
, 16, none
),
74 .name
= "window_size",
75 .type
= __type_integer(uint16_t, 0, 0, 0,
76 __BIG_ENDIAN
, 10, none
),
80 .type
= __type_integer(uint16_t, 0, 0, 0,
81 __BIG_ENDIAN
, 16, none
),
85 .type
= __type_integer(uint16_t, 0, 0, 0,
86 __BIG_ENDIAN
, 10, none
),
90 static struct lttng_event_field udpfields
[] = {
92 .name
= "source_port",
93 .type
= __type_integer(uint16_t, 0, 0, 0,
94 __BIG_ENDIAN
, 10, none
),
98 .type
= __type_integer(uint16_t, 0, 0, 0,
99 __BIG_ENDIAN
, 10, none
),
103 .type
= __type_integer(uint16_t, 0, 0, 0,
104 __BIG_ENDIAN
, 10, none
),
108 .type
= __type_integer(uint16_t, 0, 0, 0,
109 __BIG_ENDIAN
, 10, none
),
113 static struct lttng_event_field icmpfields
[] = {
116 .type
= __type_integer(uint8_t, 0, 0, 0,
117 __BIG_ENDIAN
, 10, none
),
121 .type
= __type_integer(uint8_t, 0, 0, 0,
122 __BIG_ENDIAN
, 10, none
),
126 .type
= __type_integer(uint16_t, 0, 0, 0,
127 __BIG_ENDIAN
, 10, none
),
131 .type
= __type_integer(uint32_t, 0, 0, 0,
132 __BIG_ENDIAN
, 10, none
),
137 static struct lttng_event_field transport_fields
[] = {
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,
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,
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,
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,
180 enum transport_header_types
{
187 static inline enum transport_header_types
__get_transport_header_type_ip(struct sk_buff
*skb
)
189 switch (ip_hdr(skb
)->protocol
) {
200 static inline enum transport_header_types
__get_transport_header_type_ipv6(struct sk_buff
*skb
)
202 switch (ipv6_hdr(skb
)->nexthdr
) {
213 static inline enum transport_header_types
__get_transport_header_type(struct sk_buff
*skb
)
215 if (__has_network_hdr(skb
)) {
217 * When both transport and network headers are set,
218 * transport header is greater than network header,
219 * otherwise it points to head.
221 if (skb
->transport_header
> skb
->network_header
) {
223 * Get the transport protocol from the network
224 * header's data. This method works both for
225 * sent and received packets.
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
);
233 /* Fallthrough for other cases where header is not recognized. */
238 static struct lttng_enum_entry proto_transport_enum_entries
[] = {
240 .start
= { .value
= 0, .signedness
= 0, },
241 .end
= { .value
= IPPROTO_ICMP
- 1, .signedness
= 0, },
242 .string
= "_unknown",
245 .start
= { .value
= IPPROTO_ICMP
, .signedness
= 0, },
246 .end
= { .value
= IPPROTO_ICMP
, .signedness
= 0, },
250 .start
= { .value
= IPPROTO_ICMP
+ 1, .signedness
= 0, },
251 .end
= { .value
= IPPROTO_TCP
- 1, .signedness
= 0, },
252 .string
= "_unknown",
255 .start
= { .value
= IPPROTO_TCP
, .signedness
= 0, },
256 .end
= { .value
= IPPROTO_TCP
, .signedness
= 0, },
260 .start
= { .value
= IPPROTO_TCP
+ 1, .signedness
= 0, },
261 .end
= { .value
= IPPROTO_UDP
- 1, .signedness
= 0, },
262 .string
= "_unknown",
265 .start
= { .value
= IPPROTO_UDP
, .signedness
= 0, },
266 .end
= { .value
= IPPROTO_UDP
, .signedness
= 0, },
270 .start
= { .value
= IPPROTO_UDP
+ 1, .signedness
= 0, },
271 .end
= { .value
= 255, .signedness
= 0, },
272 .string
= "_unknown",
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
),
282 static struct lttng_enum_entry transport_enum_entries
[] = {
284 .start
= { .value
= TH_NONE
, .signedness
= 0, },
285 .end
= { .value
= TH_NONE
, .signedness
= 0, },
286 .string
= "_unknown",
289 .start
= { .value
= TH_TCP
, .signedness
= 0, },
290 .end
= { .value
= TH_TCP
, .signedness
= 0, },
294 .start
= { .value
= TH_UDP
, .signedness
= 0, },
295 .end
= { .value
= TH_UDP
, .signedness
= 0, },
299 .start
= { .value
= TH_ICMP
, .signedness
= 0, },
300 .end
= { .value
= TH_ICMP
, .signedness
= 0, },
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
),
311 /* Structures for network headers. */
313 static struct lttng_event_field ipv4fields
[] = {
316 .type
= __type_integer(uint8_t, 4, 4, 0,
317 __BIG_ENDIAN
, 10, none
),
321 .type
= __type_integer(uint8_t, 4, 4, 0,
322 __BIG_ENDIAN
, 10, none
),
326 .type
= __type_integer(uint8_t, 0, 0, 0,
327 __BIG_ENDIAN
, 10, none
),
331 .type
= __type_integer(uint16_t, 0, 0, 0,
332 __BIG_ENDIAN
, 10, none
),
336 .type
= __type_integer(uint16_t, 0, 0, 0,
337 __BIG_ENDIAN
, 16, none
),
341 .type
= __type_integer(uint16_t, 0, 0, 0,
342 __BIG_ENDIAN
, 10, none
),
346 .type
= __type_integer(uint8_t, 0, 0, 0,
347 __BIG_ENDIAN
, 10, none
),
352 .atype
= atype_enum_nestable
,
353 .u
.enum_nestable
.desc
=
354 &proto_transport_header_type
,
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
)),
363 .type
= __type_integer(uint16_t, 0, 0, 0,
364 __BIG_ENDIAN
, 16, none
),
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),
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),
391 .name
= "transport_header_type",
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
)),
402 .name
= "transport_header",
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,
413 static struct lttng_event_field ipv6fields
[] = {
416 .type
= __type_integer(uint8_t, 4, 4, 0,
417 __BIG_ENDIAN
, 10, none
),
421 .type
= __type_integer(uint8_t, 4, 4, 0,
422 __BIG_ENDIAN
, 10, none
),
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),
437 .name
= "payload_len",
438 .type
= __type_integer(uint16_t, 0, 0, 0,
439 __BIG_ENDIAN
, 10, none
),
444 .atype
= atype_enum_nestable
,
445 .u
.enum_nestable
.desc
=
446 &proto_transport_header_type
,
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
)),
455 .type
= __type_integer(uint8_t, 0, 0, 0,
456 __BIG_ENDIAN
, 10, none
),
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),
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),
483 .name
= "transport_header_type",
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
)),
494 .name
= "transport_header",
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,
505 static struct lttng_event_field network_fields
[] = {
509 .atype
= atype_struct_nestable
,
510 .u
.struct_nestable
.nr_fields
= 0,
511 .u
.struct_nestable
.fields
= emptyfields
,
512 .u
.struct_nestable
.alignment
= 0,
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,
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,
535 enum network_header_types
{
541 static inline unsigned char __get_network_header_type(struct sk_buff
*skb
)
543 if (__has_network_hdr(skb
)) {
544 if (skb
->protocol
== htons(ETH_P_IPV6
))
546 else if (skb
->protocol
== htons(ETH_P_IP
))
548 /* Fallthrough for other header types. */
555 LTTNG_TRACEPOINT_ENUM(net_network_header
,
557 ctf_enum_value("_unknown", NH_NONE
)
558 ctf_enum_value("_ipv4", NH_IPV4
)
559 ctf_enum_value("_ipv6", NH_IPV6
)
563 LTTNG_TRACEPOINT_EVENT(net_dev_xmit
,
565 TP_PROTO(struct sk_buff
*skb
,
567 struct net_device
*dev
,
568 unsigned int skb_len
),
570 TP_ARGS(skb
, rc
, dev
, skb_len
),
573 ctf_integer_hex(void *, skbaddr
, skb
)
574 ctf_integer(int, rc
, rc
)
575 ctf_integer(unsigned int, len
, skb_len
)
576 ctf_string(name
, dev
->name
)
580 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template
,
582 TP_PROTO(struct sk_buff
*skb
),
587 ctf_integer_hex(void *, skbaddr
, skb
)
588 ctf_integer(unsigned int, len
, skb
->len
)
589 ctf_string(name
, skb
->dev
->name
)
590 ctf_enum(net_network_header
, unsigned char,
591 network_header_type
, __get_network_header_type(skb
))
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,
605 bool has_network_header
= false;
607 /* Copy the network header. */
608 switch (__get_network_header_type(skb
)) {
611 ctf_array_type(uint8_t, ip_hdr(skb
),
612 sizeof(struct iphdr
))
613 has_network_header
= true;
618 ctf_array_type(uint8_t, ipv6_hdr(skb
),
619 sizeof(struct ipv6hdr
))
620 has_network_header
= true;
625 * For any other network header
626 * type, there is nothing to do.
631 if (has_network_header
) {
632 enum transport_header_types th_type
=
633 __get_transport_header_type(skb
);
635 /* Transport header type field. */
636 ctf_integer_type(unsigned char, th_type
)
638 /* Copy the transport header. */
642 ctf_array_type(uint8_t, tcp_hdr(skb
),
643 sizeof(struct tcphdr
))
648 ctf_array_type(uint8_t, udp_hdr(skb
),
649 sizeof(struct udphdr
))
654 ctf_array_type(uint8_t, icmp_hdr(skb
),
655 sizeof(struct icmphdr
))
660 * For any other transport header type,
661 * there is nothing to do.
671 LTTNG_TRACEPOINT_EVENT_INSTANCE(net_dev_template
, net_dev_queue
,
673 TP_PROTO(struct sk_buff
*skb
),
678 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
684 TP_PROTO(struct sk_buff
*skb
),
689 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
695 TP_PROTO(struct sk_buff
*skb
),
700 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
702 /* Trace events for the receive entry points */
703 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_receive_entry_template
,
705 TP_PROTO(const struct sk_buff
*skb
),
710 ctf_integer_hex(const void *, skbaddr
, skb
)
714 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
716 napi_gro_frags_entry
,
718 net_napi_gro_frags_entry
,
720 TP_PROTO(const struct sk_buff
*skb
),
725 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
727 napi_gro_receive_entry
,
729 net_napi_gro_receive_entry
,
731 TP_PROTO(const struct sk_buff
*skb
),
736 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
738 netif_receive_skb_entry
,
740 net_if_receive_skb_entry
,
742 TP_PROTO(const struct sk_buff
*skb
),
747 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
753 TP_PROTO(const struct sk_buff
*skb
),
758 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
764 TP_PROTO(const struct sk_buff
*skb
),
769 #endif /* kernel > 3.14 */
771 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,0))
773 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
775 netif_receive_skb_list_entry
,
777 net_if_receive_skb_list_entry
,
779 TP_PROTO(const struct sk_buff
*skb
),
784 #endif /* kernel > 4.19 */
786 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0))
788 /* Trace events for the receive exit points */
789 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_receive_exit_template
,
796 ctf_integer(int, ret
, ret
)
800 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
804 net_napi_gro_frags_exit
,
811 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
813 napi_gro_receive_exit
,
815 net_napi_gro_receive_exit
,
822 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
824 netif_receive_skb_exit
,
826 net_if_receive_skb_exit
,
833 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
844 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
855 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
857 netif_receive_skb_list_exit
,
859 net_if_receive_skb_list_exit
,
866 #endif /* kernel > 5.0.0 */
868 #endif /* LTTNG_TRACE_NET_H */
870 /* This part must be outside protection */
871 #include <probes/define_trace.h>