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 proto_transport_enum_entries
[] = {
138 .start
= { .value
= 0, .signedness
= 0, },
139 .end
= { .value
= IPPROTO_TCP
- 1, .signedness
= 0, },
140 .string
= "_unknown",
143 .start
= { .value
= IPPROTO_TCP
, .signedness
= 0, },
144 .end
= { .value
= IPPROTO_TCP
, .signedness
= 0, },
148 .start
= { .value
= IPPROTO_TCP
+ 1, .signedness
= 0, },
149 .end
= { .value
= 255, .signedness
= 0, },
150 .string
= "_unknown",
154 static const struct lttng_enum_desc proto_transport_header_type
= {
155 .name
= "proto_transport_header_type",
156 .entries
= proto_transport_enum_entries
,
157 .nr_entries
= ARRAY_SIZE(proto_transport_enum_entries
),
160 static struct lttng_enum_entry transport_enum_entries
[] = {
162 .start
= { .value
= TH_NONE
, .signedness
= 0, },
163 .end
= { .value
= TH_NONE
, .signedness
= 0, },
164 .string
= "_unknown",
167 .start
= { .value
= TH_TCP
, .signedness
= 0, },
168 .end
= { .value
= TH_TCP
, .signedness
= 0, },
173 static const struct lttng_enum_desc transport_header_type
= {
174 .name
= "transport_header_type",
175 .entries
= transport_enum_entries
,
176 .nr_entries
= ARRAY_SIZE(transport_enum_entries
),
179 /* Structures for network headers. */
181 static struct lttng_event_field ipv4fields
[] = {
184 .type
= __type_integer(uint8_t, 4, 4, 0,
185 __BIG_ENDIAN
, 10, none
),
189 .type
= __type_integer(uint8_t, 4, 4, 0,
190 __BIG_ENDIAN
, 10, none
),
194 .type
= __type_integer(uint8_t, 0, 0, 0,
195 __BIG_ENDIAN
, 10, none
),
199 .type
= __type_integer(uint16_t, 0, 0, 0,
200 __BIG_ENDIAN
, 10, none
),
204 .type
= __type_integer(uint16_t, 0, 0, 0,
205 __BIG_ENDIAN
, 16, none
),
209 .type
= __type_integer(uint16_t, 0, 0, 0,
210 __BIG_ENDIAN
, 10, none
),
214 .type
= __type_integer(uint8_t, 0, 0, 0,
215 __BIG_ENDIAN
, 10, none
),
221 .u
.basic
.enumeration
.desc
=
222 &proto_transport_header_type
,
223 .u
.basic
.enumeration
.container_type
= {
227 .reverse_byte_order
=
228 __BIG_ENDIAN
!= __BYTE_ORDER
,
230 .encoding
= lttng_encode_none
,
236 .type
= __type_integer(uint16_t, 0, 0, 0,
237 __BIG_ENDIAN
, 16, none
),
242 .atype
= atype_array
,
244 __type_integer(uint8_t, 0, 0, 0,
245 __BIG_ENDIAN
, 10, none
),
247 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
253 .atype
= atype_array
,
255 __type_integer(uint8_t, 0, 0, 0,
256 __BIG_ENDIAN
, 10, none
),
258 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
262 .name
= "transport_header_type",
265 .u
.basic
.enumeration
.desc
= &transport_header_type
,
266 .u
.basic
.enumeration
.container_type
= {
270 .reverse_byte_order
= 0,
272 .encoding
= lttng_encode_none
,
277 .name
= "transport_header",
279 .atype
= atype_variant
,
280 .u
.variant
.tag_name
= "transport_header_type",
281 .u
.variant
.choices
= transport_fields
,
282 .u
.variant
.nr_choices
= ARRAY_SIZE(transport_fields
),
287 static struct lttng_event_field ipv6fields
[] = {
290 .type
= __type_integer(uint8_t, 4, 4, 0,
291 __BIG_ENDIAN
, 10, none
),
295 .type
= __type_integer(uint8_t, 4, 4, 0,
296 __BIG_ENDIAN
, 10, none
),
301 .atype
= atype_array
,
303 __type_integer(uint8_t, 0, 0, 0,
304 __BIG_ENDIAN
, 16, none
),
306 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
310 .name
= "payload_len",
311 .type
= __type_integer(uint16_t, 0, 0, 0,
312 __BIG_ENDIAN
, 10, none
),
318 .u
.basic
.enumeration
.desc
=
319 &proto_transport_header_type
,
320 .u
.basic
.enumeration
.container_type
= {
324 .reverse_byte_order
=
325 __BIG_ENDIAN
!= __BYTE_ORDER
,
327 .encoding
= lttng_encode_none
,
333 .type
= __type_integer(uint8_t, 0, 0, 0,
334 __BIG_ENDIAN
, 10, none
),
339 .atype
= atype_array
,
341 __type_integer(uint16_t, 0, 0, 0,
342 __BIG_ENDIAN
, 16, none
),
344 .u
.array
.elem_alignment
= lttng_alignof(uint16_t),
350 .atype
= atype_array
,
352 __type_integer(uint16_t, 0, 0, 0,
353 __BIG_ENDIAN
, 16, none
),
355 .u
.array
.elem_alignment
= lttng_alignof(uint16_t),
359 .name
= "transport_header_type",
362 .u
.basic
.enumeration
.desc
= &transport_header_type
,
363 .u
.basic
.enumeration
.container_type
= {
367 .reverse_byte_order
= 0,
369 .encoding
= lttng_encode_none
,
374 .name
= "transport_header",
376 .atype
= atype_variant
,
377 .u
.variant
.tag_name
= "transport_header_type",
378 .u
.variant
.choices
= transport_fields
,
379 .u
.variant
.nr_choices
= ARRAY_SIZE(transport_fields
),
384 static struct lttng_event_field network_fields
[] = {
388 .atype
= atype_struct
,
389 .u
._struct
.nr_fields
= 0,
390 .u
._struct
.fields
= emptyfields
,
396 .atype
= atype_struct
,
397 .u
._struct
.nr_fields
= ARRAY_SIZE(ipv4fields
),
398 .u
._struct
.fields
= ipv4fields
,
404 .atype
= atype_struct
,
405 .u
._struct
.nr_fields
= ARRAY_SIZE(ipv6fields
),
406 .u
._struct
.fields
= ipv6fields
,
411 enum network_header_types
{
417 static inline unsigned char __get_network_header_type(struct sk_buff
*skb
)
419 if (__has_network_hdr(skb
)) {
420 if (skb
->protocol
== htons(ETH_P_IPV6
))
422 else if (skb
->protocol
== htons(ETH_P_IP
))
424 /* Fallthrough for other header types. */
431 LTTNG_TRACEPOINT_ENUM(net_network_header
,
433 ctf_enum_value("_unknown", NH_NONE
)
434 ctf_enum_value("_ipv4", NH_IPV4
)
435 ctf_enum_value("_ipv6", NH_IPV6
)
439 LTTNG_TRACEPOINT_EVENT(net_dev_xmit
,
441 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
442 TP_PROTO(struct sk_buff
*skb
,
444 struct net_device
*dev
,
445 unsigned int skb_len
),
447 TP_ARGS(skb
, rc
, dev
, skb_len
),
449 TP_PROTO(struct sk_buff
*skb
,
456 ctf_integer_hex(void *, skbaddr
, skb
)
457 ctf_integer(int, rc
, rc
)
458 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
459 ctf_integer(unsigned int, len
, skb_len
)
460 ctf_string(name
, dev
->name
)
462 ctf_integer(unsigned int, len
, skb
->len
)
463 ctf_string(name
, skb
->dev
->name
)
468 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template
,
470 TP_PROTO(struct sk_buff
*skb
),
475 ctf_integer_hex(void *, skbaddr
, skb
)
476 ctf_integer(unsigned int, len
, skb
->len
)
477 ctf_string(name
, skb
->dev
->name
)
478 ctf_enum(net_network_header
, unsigned char,
479 network_header_type
, __get_network_header_type(skb
))
482 .atype
= atype_variant
,
483 .u
.variant
.tag_name
= "network_header_type",
484 .u
.variant
.choices
= network_fields
,
485 .u
.variant
.nr_choices
=
486 ARRAY_SIZE(network_fields
),
490 bool has_network_header
= false;
492 /* Copy the network header. */
493 switch (__get_network_header_type(skb
)) {
496 ctf_array_type(uint8_t, ip_hdr(skb
),
497 sizeof(struct iphdr
))
498 has_network_header
= true;
503 ctf_array_type(uint8_t, ipv6_hdr(skb
),
504 sizeof(struct ipv6hdr
))
505 has_network_header
= true;
510 * For any other network header
511 * type, there is nothing to do.
516 if (has_network_header
) {
517 enum transport_header_types th_type
=
518 __get_transport_header_type(skb
);
520 /* Transport header type field. */
521 ctf_integer_type(unsigned char, th_type
)
523 /* Copy the transport header. */
524 if (th_type
== TH_TCP
) {
526 ctf_array_type(uint8_t, tcp_hdr(skb
),
527 sizeof(struct tcphdr
))
530 * For any other transport header type,
531 * there is nothing to do.
539 LTTNG_TRACEPOINT_EVENT_INSTANCE(net_dev_template
, net_dev_queue
,
541 TP_PROTO(struct sk_buff
*skb
),
546 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
552 TP_PROTO(struct sk_buff
*skb
),
557 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
563 TP_PROTO(struct sk_buff
*skb
),
567 #endif /* LTTNG_TRACE_NET_H */
569 /* This part must be outside protection */
570 #include <probes/define_trace.h>