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 unsigned char __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
= 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 transport_header_type
= {
155 .name
= "transport_header_type",
156 .entries
= transport_enum_entries
,
157 .nr_entries
= ARRAY_SIZE(transport_enum_entries
),
160 /* Structures for network headers. */
162 static struct lttng_event_field ipv4fields
[] = {
165 .type
= __type_integer(uint8_t, 4, 4, 0,
166 __BIG_ENDIAN
, 10, none
),
170 .type
= __type_integer(uint8_t, 4, 4, 0,
171 __BIG_ENDIAN
, 10, none
),
175 .type
= __type_integer(uint8_t, 0, 0, 0,
176 __BIG_ENDIAN
, 10, none
),
180 .type
= __type_integer(uint16_t, 0, 0, 0,
181 __BIG_ENDIAN
, 10, none
),
185 .type
= __type_integer(uint16_t, 0, 0, 0,
186 __BIG_ENDIAN
, 16, none
),
190 .type
= __type_integer(uint16_t, 0, 0, 0,
191 __BIG_ENDIAN
, 10, none
),
195 .type
= __type_integer(uint8_t, 0, 0, 0,
196 __BIG_ENDIAN
, 10, none
),
202 .u
.basic
.enumeration
.desc
= &transport_header_type
,
203 .u
.basic
.enumeration
.container_type
= {
207 .reverse_byte_order
=
208 __BIG_ENDIAN
!= __BYTE_ORDER
,
210 .encoding
= lttng_encode_none
,
216 .type
= __type_integer(uint16_t, 0, 0, 0,
217 __BIG_ENDIAN
, 16, none
),
222 .atype
= atype_array
,
224 __type_integer(uint8_t, 0, 0, 0,
225 __BIG_ENDIAN
, 10, none
),
227 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
233 .atype
= atype_array
,
235 __type_integer(uint8_t, 0, 0, 0,
236 __BIG_ENDIAN
, 10, none
),
238 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
242 .name
= "transport_header",
244 .atype
= atype_variant
,
245 .u
.variant
.tag_name
= "protocol",
246 .u
.variant
.choices
= transport_fields
,
247 .u
.variant
.nr_choices
= ARRAY_SIZE(transport_fields
),
252 static struct lttng_event_field ipv6fields
[] = {
255 .type
= __type_integer(uint8_t, 4, 4, 0,
256 __BIG_ENDIAN
, 10, none
),
260 .type
= __type_integer(uint8_t, 4, 4, 0,
261 __BIG_ENDIAN
, 10, none
),
266 .atype
= atype_array
,
268 __type_integer(uint8_t, 0, 0, 0,
269 __BIG_ENDIAN
, 16, none
),
271 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
275 .name
= "payload_len",
276 .type
= __type_integer(uint16_t, 0, 0, 0,
277 __BIG_ENDIAN
, 10, none
),
283 .u
.basic
.enumeration
.desc
= &transport_header_type
,
284 .u
.basic
.enumeration
.container_type
= {
288 .reverse_byte_order
=
289 __BIG_ENDIAN
!= __BYTE_ORDER
,
291 .encoding
= lttng_encode_none
,
297 .type
= __type_integer(uint8_t, 0, 0, 0,
298 __BIG_ENDIAN
, 10, none
),
303 .atype
= atype_array
,
305 __type_integer(uint16_t, 0, 0, 0,
306 __BIG_ENDIAN
, 16, none
),
308 .u
.array
.elem_alignment
= lttng_alignof(uint16_t),
314 .atype
= atype_array
,
316 __type_integer(uint16_t, 0, 0, 0,
317 __BIG_ENDIAN
, 16, none
),
319 .u
.array
.elem_alignment
= lttng_alignof(uint16_t),
323 .name
= "transport_header",
325 .atype
= atype_variant
,
326 .u
.variant
.tag_name
= "nexthdr",
327 .u
.variant
.choices
= transport_fields
,
328 .u
.variant
.nr_choices
= ARRAY_SIZE(transport_fields
),
333 static struct lttng_event_field network_fields
[] = {
337 .atype
= atype_struct
,
338 .u
._struct
.nr_fields
= 0,
339 .u
._struct
.fields
= emptyfields
,
345 .atype
= atype_struct
,
346 .u
._struct
.nr_fields
= ARRAY_SIZE(ipv4fields
),
347 .u
._struct
.fields
= ipv4fields
,
353 .atype
= atype_struct
,
354 .u
._struct
.nr_fields
= ARRAY_SIZE(ipv6fields
),
355 .u
._struct
.fields
= ipv6fields
,
360 enum network_header_types
{
366 static inline unsigned char __get_network_header_type(struct sk_buff
*skb
)
368 if (__has_network_hdr(skb
)) {
369 if (skb
->protocol
== htons(ETH_P_IPV6
))
371 else if (skb
->protocol
== htons(ETH_P_IP
))
373 /* Fallthrough for other header types. */
380 LTTNG_TRACEPOINT_ENUM(net_network_header
,
382 ctf_enum_value("_unknown", NH_NONE
)
383 ctf_enum_value("_ipv4", NH_IPV4
)
384 ctf_enum_value("_ipv6", NH_IPV6
)
388 LTTNG_TRACEPOINT_EVENT(net_dev_xmit
,
390 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
391 TP_PROTO(struct sk_buff
*skb
,
393 struct net_device
*dev
,
394 unsigned int skb_len
),
396 TP_ARGS(skb
, rc
, dev
, skb_len
),
398 TP_PROTO(struct sk_buff
*skb
,
405 ctf_integer_hex(void *, skbaddr
, skb
)
406 ctf_integer(int, rc
, rc
)
407 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
408 ctf_integer(unsigned int, len
, skb_len
)
409 ctf_string(name
, dev
->name
)
411 ctf_integer(unsigned int, len
, skb
->len
)
412 ctf_string(name
, skb
->dev
->name
)
417 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template
,
419 TP_PROTO(struct sk_buff
*skb
),
424 ctf_integer_hex(void *, skbaddr
, skb
)
425 ctf_integer(unsigned int, len
, skb
->len
)
426 ctf_string(name
, skb
->dev
->name
)
427 ctf_enum(net_network_header
, unsigned char,
428 network_header_type
, __get_network_header_type(skb
))
431 .atype
= atype_variant
,
432 .u
.variant
.tag_name
= "network_header_type",
433 .u
.variant
.choices
= network_fields
,
434 .u
.variant
.nr_choices
=
435 ARRAY_SIZE(network_fields
),
439 /* Copy the network header. */
440 switch (__get_network_header_type(skb
)) {
443 ctf_array_type(uint8_t, ip_hdr(skb
),
444 sizeof(struct iphdr
))
449 ctf_array_type(uint8_t, ipv6_hdr(skb
),
450 sizeof(struct ipv6hdr
))
455 * For any other network header
456 * type, there is nothing to do.
461 /* Copy the transport header. */
462 if (__get_transport_header_type(skb
)
465 ctf_array_type(uint8_t, tcp_hdr(skb
),
466 sizeof(struct tcphdr
))
469 * For any other transport header type,
470 * there is nothing to do.
477 LTTNG_TRACEPOINT_EVENT_INSTANCE(net_dev_template
, net_dev_queue
,
479 TP_PROTO(struct sk_buff
*skb
),
484 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
490 TP_PROTO(struct sk_buff
*skb
),
495 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
501 TP_PROTO(struct sk_buff
*skb
),
505 #endif /* LTTNG_TRACE_NET_H */
507 /* This part must be outside protection */
508 #include <probes/define_trace.h>