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 <lttng/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 <lttng/lttng-endian.h>
19 #ifndef ONCE_LTTNG_NET_H
20 #define ONCE_LTTNG_NET_H
22 static inline unsigned char __has_network_hdr(struct sk_buff
*skb
)
25 * If the header is not set yet, the network header will point
28 return skb_network_header(skb
) != skb
->head
;
31 static struct lttng_event_field emptyfields
[] = {
34 /* Structures for transport headers. */
36 static struct lttng_event_field tcpfields
[] = {
38 .name
= "source_port",
39 .type
= __type_integer(uint16_t, 0, 0, 0,
40 __BIG_ENDIAN
, 10, none
),
44 .type
= __type_integer(uint16_t, 0, 0, 0,
45 __BIG_ENDIAN
, 10, none
),
49 .type
= __type_integer(uint32_t, 0, 0, 0,
50 __BIG_ENDIAN
, 10, none
),
54 .type
= __type_integer(uint32_t, 0, 0, 0,
55 __BIG_ENDIAN
, 10, none
),
58 .name
= "data_offset",
59 .type
= __type_integer(uint8_t, 4, 4, 0,
60 __BIG_ENDIAN
, 10, none
),
64 .type
= __type_integer(uint8_t, 3, 1, 0,
65 __BIG_ENDIAN
, 10, none
),
69 .type
= __type_integer(uint8_t, 9, 1, 0,
70 __BIG_ENDIAN
, 16, none
),
73 .name
= "window_size",
74 .type
= __type_integer(uint16_t, 0, 0, 0,
75 __BIG_ENDIAN
, 10, none
),
79 .type
= __type_integer(uint16_t, 0, 0, 0,
80 __BIG_ENDIAN
, 16, none
),
84 .type
= __type_integer(uint16_t, 0, 0, 0,
85 __BIG_ENDIAN
, 10, none
),
89 static struct lttng_event_field udpfields
[] = {
91 .name
= "source_port",
92 .type
= __type_integer(uint16_t, 0, 0, 0,
93 __BIG_ENDIAN
, 10, none
),
97 .type
= __type_integer(uint16_t, 0, 0, 0,
98 __BIG_ENDIAN
, 10, none
),
102 .type
= __type_integer(uint16_t, 0, 0, 0,
103 __BIG_ENDIAN
, 10, none
),
107 .type
= __type_integer(uint16_t, 0, 0, 0,
108 __BIG_ENDIAN
, 10, none
),
112 static struct lttng_event_field icmpfields
[] = {
115 .type
= __type_integer(uint8_t, 0, 0, 0,
116 __BIG_ENDIAN
, 10, none
),
120 .type
= __type_integer(uint8_t, 0, 0, 0,
121 __BIG_ENDIAN
, 10, none
),
125 .type
= __type_integer(uint16_t, 0, 0, 0,
126 __BIG_ENDIAN
, 10, none
),
130 .type
= __type_integer(uint32_t, 0, 0, 0,
131 __BIG_ENDIAN
, 10, none
),
136 static struct lttng_event_field transport_fields
[] = {
140 .atype
= atype_struct_nestable
,
141 .u
.struct_nestable
.nr_fields
= ARRAY_SIZE(emptyfields
),
142 .u
.struct_nestable
.fields
= emptyfields
,
143 .u
.struct_nestable
.alignment
= 0,
150 .atype
= atype_struct_nestable
,
151 .u
.struct_nestable
.nr_fields
= ARRAY_SIZE(tcpfields
),
152 .u
.struct_nestable
.fields
= tcpfields
,
153 .u
.struct_nestable
.alignment
= 0,
160 .atype
= atype_struct_nestable
,
161 .u
.struct_nestable
.nr_fields
= ARRAY_SIZE(udpfields
),
162 .u
.struct_nestable
.fields
= udpfields
,
163 .u
.struct_nestable
.alignment
= 0,
170 .atype
= atype_struct_nestable
,
171 .u
.struct_nestable
.nr_fields
= ARRAY_SIZE(icmpfields
),
172 .u
.struct_nestable
.fields
= icmpfields
,
173 .u
.struct_nestable
.alignment
= 0,
179 enum transport_header_types
{
186 static inline enum transport_header_types
__get_transport_header_type_ip(struct sk_buff
*skb
)
188 switch (ip_hdr(skb
)->protocol
) {
199 static inline enum transport_header_types
__get_transport_header_type_ipv6(struct sk_buff
*skb
)
201 switch (ipv6_hdr(skb
)->nexthdr
) {
212 static inline enum transport_header_types
__get_transport_header_type(struct sk_buff
*skb
)
214 if (__has_network_hdr(skb
)) {
216 * When both transport and network headers are set,
217 * transport header is greater than network header,
218 * otherwise it points to head.
220 if (skb
->transport_header
> skb
->network_header
) {
222 * Get the transport protocol from the network
223 * header's data. This method works both for
224 * sent and received packets.
226 if (skb
->protocol
== htons(ETH_P_IP
)) {
227 return __get_transport_header_type_ip(skb
);
228 } else if(skb
->protocol
== htons(ETH_P_IPV6
)) {
229 return __get_transport_header_type_ipv6(skb
);
232 /* Fallthrough for other cases where header is not recognized. */
237 static struct lttng_enum_entry proto_transport_enum_entries
[] = {
239 .start
= { .value
= 0, .signedness
= 0, },
240 .end
= { .value
= IPPROTO_ICMP
- 1, .signedness
= 0, },
241 .string
= "_unknown",
244 .start
= { .value
= IPPROTO_ICMP
, .signedness
= 0, },
245 .end
= { .value
= IPPROTO_ICMP
, .signedness
= 0, },
249 .start
= { .value
= IPPROTO_ICMP
+ 1, .signedness
= 0, },
250 .end
= { .value
= IPPROTO_TCP
- 1, .signedness
= 0, },
251 .string
= "_unknown",
254 .start
= { .value
= IPPROTO_TCP
, .signedness
= 0, },
255 .end
= { .value
= IPPROTO_TCP
, .signedness
= 0, },
259 .start
= { .value
= IPPROTO_TCP
+ 1, .signedness
= 0, },
260 .end
= { .value
= IPPROTO_UDP
- 1, .signedness
= 0, },
261 .string
= "_unknown",
264 .start
= { .value
= IPPROTO_UDP
, .signedness
= 0, },
265 .end
= { .value
= IPPROTO_UDP
, .signedness
= 0, },
269 .start
= { .value
= IPPROTO_UDP
+ 1, .signedness
= 0, },
270 .end
= { .value
= 255, .signedness
= 0, },
271 .string
= "_unknown",
275 static const struct lttng_enum_desc proto_transport_header_type
= {
276 .name
= "proto_transport_header_type",
277 .entries
= proto_transport_enum_entries
,
278 .nr_entries
= ARRAY_SIZE(proto_transport_enum_entries
),
281 static struct lttng_enum_entry transport_enum_entries
[] = {
283 .start
= { .value
= TH_NONE
, .signedness
= 0, },
284 .end
= { .value
= TH_NONE
, .signedness
= 0, },
285 .string
= "_unknown",
288 .start
= { .value
= TH_TCP
, .signedness
= 0, },
289 .end
= { .value
= TH_TCP
, .signedness
= 0, },
293 .start
= { .value
= TH_UDP
, .signedness
= 0, },
294 .end
= { .value
= TH_UDP
, .signedness
= 0, },
298 .start
= { .value
= TH_ICMP
, .signedness
= 0, },
299 .end
= { .value
= TH_ICMP
, .signedness
= 0, },
304 static const struct lttng_enum_desc transport_header_type
= {
305 .name
= "transport_header_type",
306 .entries
= transport_enum_entries
,
307 .nr_entries
= ARRAY_SIZE(transport_enum_entries
),
310 /* Structures for network headers. */
312 static struct lttng_event_field ipv4fields
[] = {
315 .type
= __type_integer(uint8_t, 4, 4, 0,
316 __BIG_ENDIAN
, 10, none
),
320 .type
= __type_integer(uint8_t, 4, 4, 0,
321 __BIG_ENDIAN
, 10, none
),
325 .type
= __type_integer(uint8_t, 0, 0, 0,
326 __BIG_ENDIAN
, 10, none
),
330 .type
= __type_integer(uint16_t, 0, 0, 0,
331 __BIG_ENDIAN
, 10, none
),
335 .type
= __type_integer(uint16_t, 0, 0, 0,
336 __BIG_ENDIAN
, 16, none
),
340 .type
= __type_integer(uint16_t, 0, 0, 0,
341 __BIG_ENDIAN
, 10, none
),
345 .type
= __type_integer(uint8_t, 0, 0, 0,
346 __BIG_ENDIAN
, 10, none
),
351 .atype
= atype_enum_nestable
,
352 .u
.enum_nestable
.desc
=
353 &proto_transport_header_type
,
354 .u
.enum_nestable
.container_type
=
355 __LTTNG_COMPOUND_LITERAL(struct lttng_type
,
356 __type_integer(uint8_t, 0, 0, -1,
357 __BIG_ENDIAN
, 10, none
)),
362 .type
= __type_integer(uint16_t, 0, 0, 0,
363 __BIG_ENDIAN
, 16, none
),
368 .atype
= atype_array_nestable
,
369 .u
.array_nestable
.elem_type
=
370 __LTTNG_COMPOUND_LITERAL(struct lttng_type
,
371 __type_integer(uint8_t, 0, 0, 0,
372 __BIG_ENDIAN
, 10, none
)),
373 .u
.array_nestable
.length
= 4,
374 .u
.array_nestable
.alignment
= lttng_alignof(uint8_t),
380 .atype
= atype_array_nestable
,
381 .u
.array_nestable
.elem_type
=
382 __LTTNG_COMPOUND_LITERAL(struct lttng_type
,
383 __type_integer(uint8_t, 0, 0, 0,
384 __BIG_ENDIAN
, 10, none
)),
385 .u
.array_nestable
.length
= 4,
386 .u
.array_nestable
.alignment
= lttng_alignof(uint8_t),
390 .name
= "transport_header_type",
392 .atype
= atype_enum_nestable
,
393 .u
.enum_nestable
.desc
= &transport_header_type
,
394 .u
.enum_nestable
.container_type
=
395 __LTTNG_COMPOUND_LITERAL(struct lttng_type
,
396 __type_integer(uint8_t, 0, 0, -1,
397 __BYTE_ORDER
, 10, none
)),
401 .name
= "transport_header",
403 .atype
= atype_variant_nestable
,
404 .u
.variant_nestable
.tag_name
= "transport_header_type",
405 .u
.variant_nestable
.choices
= transport_fields
,
406 .u
.variant_nestable
.nr_choices
= ARRAY_SIZE(transport_fields
),
407 .u
.variant_nestable
.alignment
= 0,
412 static struct lttng_event_field ipv6fields
[] = {
415 .type
= __type_integer(uint8_t, 4, 4, 0,
416 __BIG_ENDIAN
, 10, none
),
420 .type
= __type_integer(uint8_t, 4, 4, 0,
421 __BIG_ENDIAN
, 10, none
),
426 .atype
= atype_array_nestable
,
427 .u
.array_nestable
.elem_type
=
428 __LTTNG_COMPOUND_LITERAL(struct lttng_type
,
429 __type_integer(uint8_t, 0, 0, 0,
430 __BIG_ENDIAN
, 16, none
)),
431 .u
.array_nestable
.length
= 3,
432 .u
.array_nestable
.alignment
= lttng_alignof(uint8_t),
436 .name
= "payload_len",
437 .type
= __type_integer(uint16_t, 0, 0, 0,
438 __BIG_ENDIAN
, 10, none
),
443 .atype
= atype_enum_nestable
,
444 .u
.enum_nestable
.desc
=
445 &proto_transport_header_type
,
446 .u
.enum_nestable
.container_type
=
447 __LTTNG_COMPOUND_LITERAL(struct lttng_type
,
448 __type_integer(uint8_t, 0, 0, -1,
449 __BIG_ENDIAN
, 10, none
)),
454 .type
= __type_integer(uint8_t, 0, 0, 0,
455 __BIG_ENDIAN
, 10, none
),
460 .atype
= atype_array_nestable
,
461 .u
.array_nestable
.elem_type
=
462 __LTTNG_COMPOUND_LITERAL(struct lttng_type
,
463 __type_integer(uint16_t, 0, 0, 0,
464 __BIG_ENDIAN
, 16, none
)),
465 .u
.array_nestable
.length
= 8,
466 .u
.array_nestable
.alignment
= lttng_alignof(uint16_t),
472 .atype
= atype_array_nestable
,
473 .u
.array_nestable
.elem_type
=
474 __LTTNG_COMPOUND_LITERAL(struct lttng_type
,
475 __type_integer(uint16_t, 0, 0, 0,
476 __BIG_ENDIAN
, 16, none
)),
477 .u
.array_nestable
.length
= 8,
478 .u
.array_nestable
.alignment
= lttng_alignof(uint16_t),
482 .name
= "transport_header_type",
484 .atype
= atype_enum_nestable
,
485 .u
.enum_nestable
.desc
= &transport_header_type
,
486 .u
.enum_nestable
.container_type
=
487 __LTTNG_COMPOUND_LITERAL(struct lttng_type
,
488 __type_integer(uint8_t, 0, 0, -1,
489 __BYTE_ORDER
, 10, none
)),
493 .name
= "transport_header",
495 .atype
= atype_variant_nestable
,
496 .u
.variant_nestable
.tag_name
= "transport_header_type",
497 .u
.variant_nestable
.choices
= transport_fields
,
498 .u
.variant_nestable
.nr_choices
= ARRAY_SIZE(transport_fields
),
499 .u
.variant_nestable
.alignment
= 0,
504 static struct lttng_event_field network_fields
[] = {
508 .atype
= atype_struct_nestable
,
509 .u
.struct_nestable
.nr_fields
= 0,
510 .u
.struct_nestable
.fields
= emptyfields
,
511 .u
.struct_nestable
.alignment
= 0,
517 .atype
= atype_struct_nestable
,
518 .u
.struct_nestable
.nr_fields
= ARRAY_SIZE(ipv4fields
),
519 .u
.struct_nestable
.fields
= ipv4fields
,
520 .u
.struct_nestable
.alignment
= 0,
526 .atype
= atype_struct_nestable
,
527 .u
.struct_nestable
.nr_fields
= ARRAY_SIZE(ipv6fields
),
528 .u
.struct_nestable
.fields
= ipv6fields
,
529 .u
.struct_nestable
.alignment
= 0,
534 enum network_header_types
{
540 static inline unsigned char __get_network_header_type(struct sk_buff
*skb
)
542 if (__has_network_hdr(skb
)) {
543 if (skb
->protocol
== htons(ETH_P_IPV6
))
545 else if (skb
->protocol
== htons(ETH_P_IP
))
547 /* Fallthrough for other header types. */
554 LTTNG_TRACEPOINT_ENUM(net_network_header
,
556 ctf_enum_value("_unknown", NH_NONE
)
557 ctf_enum_value("_ipv4", NH_IPV4
)
558 ctf_enum_value("_ipv6", NH_IPV6
)
562 LTTNG_TRACEPOINT_EVENT(net_dev_xmit
,
564 TP_PROTO(struct sk_buff
*skb
,
566 struct net_device
*dev
,
567 unsigned int skb_len
),
569 TP_ARGS(skb
, rc
, dev
, skb_len
),
572 ctf_integer_hex(void *, skbaddr
, skb
)
573 ctf_integer(int, rc
, rc
)
574 ctf_integer(unsigned int, len
, skb_len
)
575 ctf_string(name
, dev
->name
)
579 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template
,
581 TP_PROTO(struct sk_buff
*skb
),
586 ctf_integer_hex(void *, skbaddr
, skb
)
587 ctf_integer(unsigned int, len
, skb
->len
)
588 ctf_string(name
, skb
->dev
->name
)
589 ctf_enum(net_network_header
, unsigned char,
590 network_header_type
, __get_network_header_type(skb
))
594 .atype
= atype_variant_nestable
,
595 .u
.variant_nestable
.tag_name
= "network_header_type",
596 .u
.variant_nestable
.choices
= network_fields
,
597 .u
.variant_nestable
.nr_choices
=
598 ARRAY_SIZE(network_fields
),
599 .u
.variant_nestable
.alignment
= 0,
604 bool has_network_header
= false;
606 /* Copy the network header. */
607 switch (__get_network_header_type(skb
)) {
610 ctf_array_type(uint8_t, ip_hdr(skb
),
611 sizeof(struct iphdr
))
612 has_network_header
= true;
617 ctf_array_type(uint8_t, ipv6_hdr(skb
),
618 sizeof(struct ipv6hdr
))
619 has_network_header
= true;
624 * For any other network header
625 * type, there is nothing to do.
630 if (has_network_header
) {
631 enum transport_header_types th_type
=
632 __get_transport_header_type(skb
);
634 /* Transport header type field. */
635 ctf_integer_type(unsigned char, th_type
)
637 /* Copy the transport header. */
641 ctf_array_type(uint8_t, tcp_hdr(skb
),
642 sizeof(struct tcphdr
))
647 ctf_array_type(uint8_t, udp_hdr(skb
),
648 sizeof(struct udphdr
))
653 ctf_array_type(uint8_t, icmp_hdr(skb
),
654 sizeof(struct icmphdr
))
659 * For any other transport header type,
660 * there is nothing to do.
670 LTTNG_TRACEPOINT_EVENT_INSTANCE(net_dev_template
, net_dev_queue
,
672 TP_PROTO(struct sk_buff
*skb
),
677 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
683 TP_PROTO(struct sk_buff
*skb
),
688 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
694 TP_PROTO(struct sk_buff
*skb
),
699 /* Trace events for the receive entry points */
700 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_receive_entry_template
,
702 TP_PROTO(const struct sk_buff
*skb
),
707 ctf_integer_hex(const void *, skbaddr
, skb
)
711 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
713 napi_gro_frags_entry
,
715 net_napi_gro_frags_entry
,
717 TP_PROTO(const struct sk_buff
*skb
),
722 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
724 napi_gro_receive_entry
,
726 net_napi_gro_receive_entry
,
728 TP_PROTO(const struct sk_buff
*skb
),
733 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
735 netif_receive_skb_entry
,
737 net_if_receive_skb_entry
,
739 TP_PROTO(const struct sk_buff
*skb
),
744 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
750 TP_PROTO(const struct sk_buff
*skb
),
755 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
761 TP_PROTO(const struct sk_buff
*skb
),
766 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
768 netif_receive_skb_list_entry
,
770 net_if_receive_skb_list_entry
,
772 TP_PROTO(const struct sk_buff
*skb
),
777 /* Trace events for the receive exit points */
778 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_receive_exit_template
,
785 ctf_integer(int, ret
, ret
)
789 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
793 net_napi_gro_frags_exit
,
800 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
802 napi_gro_receive_exit
,
804 net_napi_gro_receive_exit
,
811 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
813 netif_receive_skb_exit
,
815 net_if_receive_skb_exit
,
822 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
833 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
844 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
846 netif_receive_skb_list_exit
,
848 net_if_receive_skb_list_exit
,
855 #endif /* LTTNG_TRACE_NET_H */
857 /* This part must be outside protection */
858 #include <lttng/define_trace.h>