2 #define TRACE_SYSTEM net
4 #if !defined(LTTNG_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ)
5 #define LTTNG_TRACE_NET_H
7 #include <probes/lttng-tracepoint-event.h>
8 #include <linux/skbuff.h>
9 #include <linux/netdevice.h>
11 #include <linux/ipv6.h>
12 #include <linux/tcp.h>
13 #include <linux/version.h>
14 #include <lttng-endian.h>
17 #ifndef ONCE_LTTNG_NET_H
18 #define ONCE_LTTNG_NET_H
20 static inline unsigned char __has_network_hdr(struct sk_buff
*skb
)
23 * If the header is not set yet, the network header will point
26 return skb_network_header(skb
) != skb
->head
;
29 static struct lttng_event_field emptyfields
[] = {
32 /* Structures for transport headers. */
34 static struct lttng_event_field tcpfields
[] = {
36 .name
= "source_port",
37 .type
= __type_integer(uint16_t, 0, 0, 0,
38 __BIG_ENDIAN
, 10, none
),
42 .type
= __type_integer(uint16_t, 0, 0, 0,
43 __BIG_ENDIAN
, 10, none
),
47 .type
= __type_integer(uint32_t, 0, 0, 0,
48 __BIG_ENDIAN
, 10, none
),
52 .type
= __type_integer(uint32_t, 0, 0, 0,
53 __BIG_ENDIAN
, 10, none
),
56 .name
= "data_offset",
57 .type
= __type_integer(uint8_t, 4, 4, 0,
58 __BIG_ENDIAN
, 10, none
),
62 .type
= __type_integer(uint8_t, 3, 1, 0,
63 __BIG_ENDIAN
, 10, none
),
67 .type
= __type_integer(uint8_t, 9, 1, 0,
68 __BIG_ENDIAN
, 16, none
),
71 .name
= "window_size",
72 .type
= __type_integer(uint16_t, 0, 0, 0,
73 __BIG_ENDIAN
, 10, none
),
77 .type
= __type_integer(uint16_t, 0, 0, 0,
78 __BIG_ENDIAN
, 16, none
),
82 .type
= __type_integer(uint16_t, 0, 0, 0,
83 __BIG_ENDIAN
, 10, none
),
87 static struct lttng_event_field transport_fields
[] = {
91 .atype
= atype_struct
,
92 .u
._struct
.nr_fields
= ARRAY_SIZE(emptyfields
),
93 .u
._struct
.fields
= emptyfields
,
99 .atype
= atype_struct
,
100 .u
._struct
.nr_fields
= ARRAY_SIZE(tcpfields
),
101 .u
._struct
.fields
= tcpfields
,
106 enum transport_header_types
{
111 static inline enum transport_header_types
__get_transport_header_type(struct sk_buff
*skb
)
113 if (__has_network_hdr(skb
)) {
115 * When both transport and network headers are set,
116 * transport header is greater than network header,
117 * otherwise it points to head.
119 if (skb
->transport_header
> skb
->network_header
) {
121 * Get the transport protocol from the network
122 * header's data. This method works both for
123 * sent and received packets.
125 if ((skb
->protocol
== htons(ETH_P_IP
) &&
126 ip_hdr(skb
)->protocol
== IPPROTO_TCP
) ||
127 (skb
->protocol
== htons(ETH_P_IPV6
) &&
128 ipv6_hdr(skb
)->nexthdr
== IPPROTO_TCP
))
131 /* Fallthrough for other cases where header is not TCP. */
136 static struct lttng_enum_entry transport_enum_entries
[] = {
138 .start
= { .value
= TH_NONE
, .signedness
= 0, },
139 .end
= { .value
= TH_NONE
, .signedness
= 0, },
140 .string
= "_unknown",
143 .start
= { .value
= TH_TCP
, .signedness
= 0, },
144 .end
= { .value
= TH_TCP
, .signedness
= 0, },
149 static const struct lttng_enum_desc transport_header_type
= {
150 .name
= "transport_header_type",
151 .entries
= transport_enum_entries
,
152 .nr_entries
= ARRAY_SIZE(transport_enum_entries
),
155 /* Structures for network headers. */
157 static struct lttng_event_field ipv4fields
[] = {
160 .type
= __type_integer(uint8_t, 4, 4, 0,
161 __BIG_ENDIAN
, 10, none
),
165 .type
= __type_integer(uint8_t, 4, 4, 0,
166 __BIG_ENDIAN
, 10, none
),
170 .type
= __type_integer(uint8_t, 0, 0, 0,
171 __BIG_ENDIAN
, 10, none
),
175 .type
= __type_integer(uint16_t, 0, 0, 0,
176 __BIG_ENDIAN
, 10, none
),
180 .type
= __type_integer(uint16_t, 0, 0, 0,
181 __BIG_ENDIAN
, 16, none
),
185 .type
= __type_integer(uint16_t, 0, 0, 0,
186 __BIG_ENDIAN
, 10, none
),
190 .type
= __type_integer(uint8_t, 0, 0, 0,
191 __BIG_ENDIAN
, 10, none
),
197 .u
.basic
.enumeration
.desc
= &transport_header_type
,
198 .u
.basic
.enumeration
.container_type
= {
202 .reverse_byte_order
=
203 __BIG_ENDIAN
!= __BYTE_ORDER
,
205 .encoding
= lttng_encode_none
,
211 .type
= __type_integer(uint16_t, 0, 0, 0,
212 __BIG_ENDIAN
, 16, none
),
217 .atype
= atype_array
,
219 __type_integer(uint8_t, 0, 0, 0,
220 __BIG_ENDIAN
, 10, none
),
222 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
228 .atype
= atype_array
,
230 __type_integer(uint8_t, 0, 0, 0,
231 __BIG_ENDIAN
, 10, none
),
233 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
237 .name
= "transport_header_type",
240 .u
.basic
.enumeration
.desc
= &transport_header_type
,
241 .u
.basic
.enumeration
.container_type
= {
245 .reverse_byte_order
= 0,
247 .encoding
= lttng_encode_none
,
252 .name
= "transport_header",
254 .atype
= atype_variant
,
255 .u
.variant
.tag_name
= "transport_header_type",
256 .u
.variant
.choices
= transport_fields
,
257 .u
.variant
.nr_choices
= ARRAY_SIZE(transport_fields
),
262 static struct lttng_event_field ipv6fields
[] = {
265 .type
= __type_integer(uint8_t, 4, 4, 0,
266 __BIG_ENDIAN
, 10, none
),
270 .type
= __type_integer(uint8_t, 4, 4, 0,
271 __BIG_ENDIAN
, 10, none
),
276 .atype
= atype_array
,
278 __type_integer(uint8_t, 0, 0, 0,
279 __BIG_ENDIAN
, 16, none
),
281 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
285 .name
= "payload_len",
286 .type
= __type_integer(uint16_t, 0, 0, 0,
287 __BIG_ENDIAN
, 10, none
),
293 .u
.basic
.enumeration
.desc
= &transport_header_type
,
294 .u
.basic
.enumeration
.container_type
= {
298 .reverse_byte_order
=
299 __BIG_ENDIAN
!= __BYTE_ORDER
,
301 .encoding
= lttng_encode_none
,
307 .type
= __type_integer(uint8_t, 0, 0, 0,
308 __BIG_ENDIAN
, 10, none
),
313 .atype
= atype_array
,
315 __type_integer(uint16_t, 0, 0, 0,
316 __BIG_ENDIAN
, 16, none
),
318 .u
.array
.elem_alignment
= lttng_alignof(uint16_t),
324 .atype
= atype_array
,
326 __type_integer(uint16_t, 0, 0, 0,
327 __BIG_ENDIAN
, 16, none
),
329 .u
.array
.elem_alignment
= lttng_alignof(uint16_t),
333 .name
= "transport_header_type",
336 .u
.basic
.enumeration
.desc
= &transport_header_type
,
337 .u
.basic
.enumeration
.container_type
= {
341 .reverse_byte_order
= 0,
343 .encoding
= lttng_encode_none
,
348 .name
= "transport_header",
350 .atype
= atype_variant
,
351 .u
.variant
.tag_name
= "transport_header_type",
352 .u
.variant
.choices
= transport_fields
,
353 .u
.variant
.nr_choices
= ARRAY_SIZE(transport_fields
),
358 static struct lttng_event_field network_fields
[] = {
362 .atype
= atype_struct
,
363 .u
._struct
.nr_fields
= 0,
364 .u
._struct
.fields
= emptyfields
,
370 .atype
= atype_struct
,
371 .u
._struct
.nr_fields
= ARRAY_SIZE(ipv4fields
),
372 .u
._struct
.fields
= ipv4fields
,
378 .atype
= atype_struct
,
379 .u
._struct
.nr_fields
= ARRAY_SIZE(ipv6fields
),
380 .u
._struct
.fields
= ipv6fields
,
385 enum network_header_types
{
391 static inline unsigned char __get_network_header_type(struct sk_buff
*skb
)
393 if (__has_network_hdr(skb
)) {
394 if (skb
->protocol
== htons(ETH_P_IPV6
))
396 else if (skb
->protocol
== htons(ETH_P_IP
))
398 /* Fallthrough for other header types. */
405 LTTNG_TRACEPOINT_ENUM(net_network_header
,
407 ctf_enum_value("_unknown", NH_NONE
)
408 ctf_enum_value("_ipv4", NH_IPV4
)
409 ctf_enum_value("_ipv6", NH_IPV6
)
413 LTTNG_TRACEPOINT_EVENT(net_dev_xmit
,
415 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
416 TP_PROTO(struct sk_buff
*skb
,
418 struct net_device
*dev
,
419 unsigned int skb_len
),
421 TP_ARGS(skb
, rc
, dev
, skb_len
),
423 TP_PROTO(struct sk_buff
*skb
,
430 ctf_integer_hex(void *, skbaddr
, skb
)
431 ctf_integer(int, rc
, rc
)
432 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
433 ctf_integer(unsigned int, len
, skb_len
)
434 ctf_string(name
, dev
->name
)
436 ctf_integer(unsigned int, len
, skb
->len
)
437 ctf_string(name
, skb
->dev
->name
)
442 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template
,
444 TP_PROTO(struct sk_buff
*skb
),
449 ctf_integer_hex(void *, skbaddr
, skb
)
450 ctf_integer(unsigned int, len
, skb
->len
)
451 ctf_string(name
, skb
->dev
->name
)
452 ctf_enum(net_network_header
, unsigned char,
453 network_header_type
, __get_network_header_type(skb
))
456 .atype
= atype_variant
,
457 .u
.variant
.tag_name
= "network_header_type",
458 .u
.variant
.choices
= network_fields
,
459 .u
.variant
.nr_choices
=
460 ARRAY_SIZE(network_fields
),
464 bool has_network_header
= false;
466 /* Copy the network header. */
467 switch (__get_network_header_type(skb
)) {
470 ctf_array_type(uint8_t, ip_hdr(skb
),
471 sizeof(struct iphdr
))
472 has_network_header
= true;
477 ctf_array_type(uint8_t, ipv6_hdr(skb
),
478 sizeof(struct ipv6hdr
))
479 has_network_header
= true;
484 * For any other network header
485 * type, there is nothing to do.
490 if (has_network_header
) {
491 enum transport_header_types th_type
=
492 __get_transport_header_type(skb
);
494 /* Transport header type field. */
495 ctf_integer_type(unsigned char, th_type
)
497 /* Copy the transport header. */
498 if (th_type
== TH_TCP
) {
500 ctf_array_type(uint8_t, tcp_hdr(skb
),
501 sizeof(struct tcphdr
))
504 * For any other transport header type,
505 * there is nothing to do.
513 LTTNG_TRACEPOINT_EVENT_INSTANCE(net_dev_template
, net_dev_queue
,
515 TP_PROTO(struct sk_buff
*skb
),
520 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
526 TP_PROTO(struct sk_buff
*skb
),
531 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
537 TP_PROTO(struct sk_buff
*skb
),
541 #endif /* LTTNG_TRACE_NET_H */
543 /* This part must be outside protection */
544 #include <probes/define_trace.h>