1 /* SPDX-License-Identifier: GPL-2.0 */
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 <lttng-kernel-version.h>
15 #include <lttng-endian.h>
18 #ifndef ONCE_LTTNG_NET_H
19 #define ONCE_LTTNG_NET_H
21 static inline unsigned char __has_network_hdr(struct sk_buff
*skb
)
24 * If the header is not set yet, the network header will point
27 return skb_network_header(skb
) != skb
->head
;
30 static struct lttng_event_field emptyfields
[] = {
33 /* Structures for transport headers. */
35 static struct lttng_event_field tcpfields
[] = {
37 .name
= "source_port",
38 .type
= __type_integer(uint16_t, 0, 0, 0,
39 __BIG_ENDIAN
, 0, 10, none
),
43 .type
= __type_integer(uint16_t, 0, 0, 0,
44 __BIG_ENDIAN
, 0, 10, none
),
48 .type
= __type_integer(uint32_t, 0, 0, 0,
49 __BIG_ENDIAN
, 0, 10, none
),
53 .type
= __type_integer(uint32_t, 0, 0, 0,
54 __BIG_ENDIAN
, 0, 10, none
),
57 .name
= "data_offset",
58 .type
= __type_integer(uint8_t, 4, 4, 0,
59 __BIG_ENDIAN
, 0, 10, none
),
63 .type
= __type_integer(uint8_t, 3, 1, 0,
64 __BIG_ENDIAN
, 0, 10, none
),
68 .type
= __type_integer(uint8_t, 9, 1, 0,
69 __BIG_ENDIAN
, 0, 16, none
),
72 .name
= "window_size",
73 .type
= __type_integer(uint16_t, 0, 0, 0,
74 __BIG_ENDIAN
, 0, 10, none
),
78 .type
= __type_integer(uint16_t, 0, 0, 0,
79 __BIG_ENDIAN
, 0, 16, none
),
83 .type
= __type_integer(uint16_t, 0, 0, 0,
84 __BIG_ENDIAN
, 0, 10, none
),
88 static struct lttng_event_field transport_fields
[] = {
92 .atype
= atype_struct
,
93 .u
._struct
.nr_fields
= ARRAY_SIZE(emptyfields
),
94 .u
._struct
.fields
= emptyfields
,
100 .atype
= atype_struct
,
101 .u
._struct
.nr_fields
= ARRAY_SIZE(tcpfields
),
102 .u
._struct
.fields
= tcpfields
,
107 enum transport_header_types
{
112 static inline enum transport_header_types
__get_transport_header_type(struct sk_buff
*skb
)
114 if (__has_network_hdr(skb
)) {
116 * When both transport and network headers are set,
117 * transport header is greater than network header,
118 * otherwise it points to head.
120 if (skb
->transport_header
> skb
->network_header
) {
122 * Get the transport protocol from the network
123 * header's data. This method works both for
124 * sent and received packets.
126 if ((skb
->protocol
== htons(ETH_P_IP
) &&
127 ip_hdr(skb
)->protocol
== IPPROTO_TCP
) ||
128 (skb
->protocol
== htons(ETH_P_IPV6
) &&
129 ipv6_hdr(skb
)->nexthdr
== IPPROTO_TCP
))
132 /* Fallthrough for other cases where header is not TCP. */
137 static struct lttng_enum_entry proto_transport_enum_entries
[] = {
139 .start
= { .value
= 0, .signedness
= 0, },
140 .end
= { .value
= IPPROTO_TCP
- 1, .signedness
= 0, },
141 .string
= "_unknown",
144 .start
= { .value
= IPPROTO_TCP
, .signedness
= 0, },
145 .end
= { .value
= IPPROTO_TCP
, .signedness
= 0, },
149 .start
= { .value
= IPPROTO_TCP
+ 1, .signedness
= 0, },
150 .end
= { .value
= 255, .signedness
= 0, },
151 .string
= "_unknown",
155 static const struct lttng_enum_desc proto_transport_header_type
= {
156 .name
= "proto_transport_header_type",
157 .entries
= proto_transport_enum_entries
,
158 .nr_entries
= ARRAY_SIZE(proto_transport_enum_entries
),
161 static struct lttng_enum_entry transport_enum_entries
[] = {
163 .start
= { .value
= TH_NONE
, .signedness
= 0, },
164 .end
= { .value
= TH_NONE
, .signedness
= 0, },
165 .string
= "_unknown",
168 .start
= { .value
= TH_TCP
, .signedness
= 0, },
169 .end
= { .value
= TH_TCP
, .signedness
= 0, },
174 static const struct lttng_enum_desc transport_header_type
= {
175 .name
= "transport_header_type",
176 .entries
= transport_enum_entries
,
177 .nr_entries
= ARRAY_SIZE(transport_enum_entries
),
180 /* Structures for network headers. */
182 static struct lttng_event_field ipv4fields
[] = {
185 .type
= __type_integer(uint8_t, 4, 4, 0,
186 __BIG_ENDIAN
, 0, 10, none
),
190 .type
= __type_integer(uint8_t, 4, 4, 0,
191 __BIG_ENDIAN
, 0, 10, none
),
195 .type
= __type_integer(uint8_t, 0, 0, 0,
196 __BIG_ENDIAN
, 0, 10, none
),
200 .type
= __type_integer(uint16_t, 0, 0, 0,
201 __BIG_ENDIAN
, 0, 10, none
),
205 .type
= __type_integer(uint16_t, 0, 0, 0,
206 __BIG_ENDIAN
, 0, 16, none
),
210 .type
= __type_integer(uint16_t, 0, 0, 0,
211 __BIG_ENDIAN
, 0, 10, none
),
215 .type
= __type_integer(uint8_t, 0, 0, 0,
216 __BIG_ENDIAN
, 0, 10, none
),
222 .u
.basic
.enumeration
.desc
=
223 &proto_transport_header_type
,
224 .u
.basic
.enumeration
.container_type
= {
228 .reverse_byte_order
=
229 __BIG_ENDIAN
!= __BYTE_ORDER
,
232 .encoding
= lttng_encode_none
,
238 .type
= __type_integer(uint16_t, 0, 0, 0,
239 __BIG_ENDIAN
, 0, 16, none
),
244 .atype
= atype_array
,
246 __type_integer(uint8_t, 0, 0, 0,
247 __BIG_ENDIAN
, 0, 10, none
),
249 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
255 .atype
= atype_array
,
257 __type_integer(uint8_t, 0, 0, 0,
258 __BIG_ENDIAN
, 0, 10, none
),
260 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
264 .name
= "transport_header_type",
267 .u
.basic
.enumeration
.desc
= &transport_header_type
,
268 .u
.basic
.enumeration
.container_type
= {
272 .reverse_byte_order
= 0,
275 .encoding
= lttng_encode_none
,
280 .name
= "transport_header",
282 .atype
= atype_variant
,
283 .u
.variant
.tag_name
= "transport_header_type",
284 .u
.variant
.choices
= transport_fields
,
285 .u
.variant
.nr_choices
= ARRAY_SIZE(transport_fields
),
290 static struct lttng_event_field ipv6fields
[] = {
293 .type
= __type_integer(uint8_t, 4, 4, 0,
294 __BIG_ENDIAN
, 0, 10, none
),
298 .type
= __type_integer(uint8_t, 4, 4, 0,
299 __BIG_ENDIAN
, 0, 10, none
),
304 .atype
= atype_array
,
306 __type_integer(uint8_t, 0, 0, 0,
307 __BIG_ENDIAN
, 0, 16, none
),
309 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
313 .name
= "payload_len",
314 .type
= __type_integer(uint16_t, 0, 0, 0,
315 __BIG_ENDIAN
, 0, 10, none
),
321 .u
.basic
.enumeration
.desc
=
322 &proto_transport_header_type
,
323 .u
.basic
.enumeration
.container_type
= {
327 .reverse_byte_order
=
328 __BIG_ENDIAN
!= __BYTE_ORDER
,
331 .encoding
= lttng_encode_none
,
337 .type
= __type_integer(uint8_t, 0, 0, 0,
338 __BIG_ENDIAN
, 0, 10, none
),
343 .atype
= atype_array
,
345 __type_integer(uint16_t, 0, 0, 0,
346 __BIG_ENDIAN
, 0, 16, none
),
348 .u
.array
.elem_alignment
= lttng_alignof(uint16_t),
354 .atype
= atype_array
,
356 __type_integer(uint16_t, 0, 0, 0,
357 __BIG_ENDIAN
, 0, 16, none
),
359 .u
.array
.elem_alignment
= lttng_alignof(uint16_t),
363 .name
= "transport_header_type",
366 .u
.basic
.enumeration
.desc
= &transport_header_type
,
367 .u
.basic
.enumeration
.container_type
= {
371 .reverse_byte_order
= 0,
374 .encoding
= lttng_encode_none
,
379 .name
= "transport_header",
381 .atype
= atype_variant
,
382 .u
.variant
.tag_name
= "transport_header_type",
383 .u
.variant
.choices
= transport_fields
,
384 .u
.variant
.nr_choices
= ARRAY_SIZE(transport_fields
),
389 static struct lttng_event_field network_fields
[] = {
393 .atype
= atype_struct
,
394 .u
._struct
.nr_fields
= 0,
395 .u
._struct
.fields
= emptyfields
,
401 .atype
= atype_struct
,
402 .u
._struct
.nr_fields
= ARRAY_SIZE(ipv4fields
),
403 .u
._struct
.fields
= ipv4fields
,
409 .atype
= atype_struct
,
410 .u
._struct
.nr_fields
= ARRAY_SIZE(ipv6fields
),
411 .u
._struct
.fields
= ipv6fields
,
416 enum network_header_types
{
422 static inline unsigned char __get_network_header_type(struct sk_buff
*skb
)
424 if (__has_network_hdr(skb
)) {
425 if (skb
->protocol
== htons(ETH_P_IPV6
))
427 else if (skb
->protocol
== htons(ETH_P_IP
))
429 /* Fallthrough for other header types. */
436 LTTNG_TRACEPOINT_ENUM(net_network_header
,
438 ctf_enum_value("_unknown", NH_NONE
)
439 ctf_enum_value("_ipv4", NH_IPV4
)
440 ctf_enum_value("_ipv6", NH_IPV6
)
444 LTTNG_TRACEPOINT_EVENT(net_dev_xmit
,
446 TP_PROTO(struct sk_buff
*skb
,
448 struct net_device
*dev
,
449 unsigned int skb_len
),
451 TP_ARGS(skb
, rc
, dev
, skb_len
),
454 ctf_integer_hex(void *, skbaddr
, skb
)
455 ctf_integer(int, rc
, rc
)
456 ctf_integer(unsigned int, len
, skb_len
)
457 ctf_string(name
, dev
->name
)
461 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template
,
463 TP_PROTO(struct sk_buff
*skb
),
468 ctf_integer_hex(void *, skbaddr
, skb
)
469 ctf_integer(unsigned int, len
, skb
->len
)
470 ctf_string(name
, skb
->dev
->name
)
471 ctf_enum(net_network_header
, unsigned char,
472 network_header_type
, __get_network_header_type(skb
))
475 .atype
= atype_variant
,
476 .u
.variant
.tag_name
= "network_header_type",
477 .u
.variant
.choices
= network_fields
,
478 .u
.variant
.nr_choices
=
479 ARRAY_SIZE(network_fields
),
483 bool has_network_header
= false;
485 /* Copy the network header. */
486 switch (__get_network_header_type(skb
)) {
489 ctf_array_type(uint8_t, ip_hdr(skb
),
490 sizeof(struct iphdr
))
491 has_network_header
= true;
496 ctf_array_type(uint8_t, ipv6_hdr(skb
),
497 sizeof(struct ipv6hdr
))
498 has_network_header
= true;
503 * For any other network header
504 * type, there is nothing to do.
509 if (has_network_header
) {
510 enum transport_header_types th_type
=
511 __get_transport_header_type(skb
);
513 /* Transport header type field. */
514 ctf_integer_type(unsigned char, th_type
)
516 /* Copy the transport header. */
517 if (th_type
== TH_TCP
) {
519 ctf_array_type(uint8_t, tcp_hdr(skb
),
520 sizeof(struct tcphdr
))
523 * For any other transport header type,
524 * there is nothing to do.
532 LTTNG_TRACEPOINT_EVENT_INSTANCE(net_dev_template
, net_dev_queue
,
534 TP_PROTO(struct sk_buff
*skb
),
539 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
545 TP_PROTO(struct sk_buff
*skb
),
550 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
556 TP_PROTO(struct sk_buff
*skb
),
561 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(3,14,0))
563 /* Trace events for the receive entry points */
564 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_receive_entry_template
,
566 TP_PROTO(const struct sk_buff
*skb
),
571 ctf_integer_hex(const void *, skbaddr
, skb
)
575 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
577 napi_gro_frags_entry
,
579 net_napi_gro_frags_entry
,
581 TP_PROTO(const struct sk_buff
*skb
),
586 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
588 napi_gro_receive_entry
,
590 net_napi_gro_receive_entry
,
592 TP_PROTO(const struct sk_buff
*skb
),
597 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
599 netif_receive_skb_entry
,
601 net_if_receive_skb_entry
,
603 TP_PROTO(const struct sk_buff
*skb
),
608 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
614 TP_PROTO(const struct sk_buff
*skb
),
619 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
625 TP_PROTO(const struct sk_buff
*skb
),
630 #endif /* kernel > 3.14 */
632 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,19,0))
634 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
636 netif_receive_skb_list_entry
,
638 net_if_receive_skb_list_entry
,
640 TP_PROTO(const struct sk_buff
*skb
),
645 #endif /* kernel > 4.19 */
647 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,0,0))
649 /* Trace events for the receive exit points */
650 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_receive_exit_template
,
657 ctf_integer(int, ret
, ret
)
661 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
665 net_napi_gro_frags_exit
,
672 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
674 napi_gro_receive_exit
,
676 net_napi_gro_receive_exit
,
683 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
685 netif_receive_skb_exit
,
687 net_if_receive_skb_exit
,
694 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
705 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
716 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
718 netif_receive_skb_list_exit
,
720 net_if_receive_skb_list_exit
,
727 #endif /* kernel > 5.0.0 */
729 #endif /* LTTNG_TRACE_NET_H */
731 /* This part must be outside protection */
732 #include <probes/define_trace.h>