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,
24 * the network header will point to the head.
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, __BIG_ENDIAN
, 10, none
),
41 .type
= __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
45 .type
= __type_integer(uint32_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
49 .type
= __type_integer(uint32_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
52 .name
= "data_offset",
53 .type
= __type_integer(uint8_t, 4, 4, 0, __BIG_ENDIAN
, 10, none
),
57 .type
= __type_integer(uint8_t, 3, 1, 0, __BIG_ENDIAN
, 10, none
),
61 .type
= __type_integer(uint8_t, 9, 1, 0, __BIG_ENDIAN
, 16, none
),
64 .name
= "window_size",
65 .type
= __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
69 .type
= __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN
, 16, none
),
73 .type
= __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
77 static struct lttng_event_field transport_fields
[] = {
81 .atype
= atype_struct
,
82 .u
._struct
.nr_fields
= ARRAY_SIZE(emptyfields
),
83 .u
._struct
.fields
= emptyfields
,
89 .atype
= atype_struct
,
90 .u
._struct
.nr_fields
= ARRAY_SIZE(tcpfields
),
91 .u
._struct
.fields
= tcpfields
,
96 enum transport_header_types
{
101 static inline unsigned char __get_transport_header_type(struct sk_buff
*skb
)
103 if (__has_network_hdr(skb
)) {
105 * When both transport and network header are set, transport header
106 * is greater than network header, otherwise it points to head.
108 if (skb
->transport_header
> skb
->network_header
) {
110 * Get the transport protocol from the network header's data.
111 * This method works both for sent and received packets.
113 if ((skb
->protocol
== htons(ETH_P_IP
) &&
114 ip_hdr(skb
)->protocol
== IPPROTO_TCP
) ||
115 (skb
->protocol
== htons(ETH_P_IPV6
) &&
116 ipv6_hdr(skb
)->nexthdr
== IPPROTO_TCP
))
119 /* Fallthrough for other cases where header is not TCP. */
124 static struct lttng_enum_entry transport_enum_entries
[] = {
126 .start
= { .value
= 0, .signedness
= 0, },
127 .end
= { .value
= IPPROTO_TCP
- 1, .signedness
= 0, },
128 .string
= "_unknown",
131 .start
= { .value
= IPPROTO_TCP
, .signedness
= 0, },
132 .end
= { .value
= IPPROTO_TCP
, .signedness
= 0, },
136 .start
= { .value
= IPPROTO_TCP
+ 1, .signedness
= 0, },
137 .end
= { .value
= 255, .signedness
= 0, },
138 .string
= "_unknown",
142 static const struct lttng_enum_desc transport_header_type
= {
143 .name
= "transport_header_type",
144 .entries
= transport_enum_entries
,
145 .nr_entries
= ARRAY_SIZE(transport_enum_entries
),
148 /* Structures for network headers. */
150 static struct lttng_event_field ipv4fields
[] = {
153 .type
= __type_integer(uint8_t, 4, 4, 0, __BIG_ENDIAN
, 10, none
),
157 .type
= __type_integer(uint8_t, 4, 4, 0, __BIG_ENDIAN
, 10, none
),
161 .type
= __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
165 .type
= __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
169 .type
= __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN
, 16, none
),
173 .type
= __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
177 .type
= __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
183 .u
.basic
.enumeration
.desc
= &transport_header_type
,
184 .u
.basic
.enumeration
.container_type
= {
188 .reverse_byte_order
= __BIG_ENDIAN
!= __BYTE_ORDER
,
190 .encoding
= lttng_encode_none
,
196 .type
= __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN
, 16, none
),
201 .atype
= atype_array
,
202 .u
.array
.elem_type
= __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
204 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
210 .atype
= atype_array
,
211 .u
.array
.elem_type
= __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
213 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
217 .name
= "transport_header",
219 .atype
= atype_variant
,
220 .u
.variant
.tag_name
= "protocol",
221 .u
.variant
.choices
= transport_fields
,
222 .u
.variant
.nr_choices
= ARRAY_SIZE(transport_fields
),
227 static struct lttng_event_field ipv6fields
[] = {
230 .type
= __type_integer(uint8_t, 4, 4, 0, __BIG_ENDIAN
, 10, none
),
234 .type
= __type_integer(uint8_t, 4, 4, 0, __BIG_ENDIAN
, 10, none
),
239 .atype
= atype_array
,
240 .u
.array
.elem_type
= __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN
, 16, none
),
242 .u
.array
.elem_alignment
= lttng_alignof(uint8_t),
246 .name
= "payload_len",
247 .type
= __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
253 .u
.basic
.enumeration
.desc
= &transport_header_type
,
254 .u
.basic
.enumeration
.container_type
= {
258 .reverse_byte_order
= __BIG_ENDIAN
!= __BYTE_ORDER
,
260 .encoding
= lttng_encode_none
,
266 .type
= __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN
, 10, none
),
271 .atype
= atype_array
,
272 .u
.array
.elem_type
= __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN
, 16, none
),
274 .u
.array
.elem_alignment
= lttng_alignof(uint16_t),
280 .atype
= atype_array
,
281 .u
.array
.elem_type
= __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN
, 16, none
),
283 .u
.array
.elem_alignment
= lttng_alignof(uint16_t),
287 .name
= "transport_header",
289 .atype
= atype_variant
,
290 .u
.variant
.tag_name
= "nexthdr",
291 .u
.variant
.choices
= transport_fields
,
292 .u
.variant
.nr_choices
= ARRAY_SIZE(transport_fields
),
297 static struct lttng_event_field network_fields
[] = {
301 .atype
= atype_struct
,
302 .u
._struct
.nr_fields
= 0,
303 .u
._struct
.fields
= emptyfields
,
309 .atype
= atype_struct
,
310 .u
._struct
.nr_fields
= ARRAY_SIZE(ipv4fields
),
311 .u
._struct
.fields
= ipv4fields
,
317 .atype
= atype_struct
,
318 .u
._struct
.nr_fields
= ARRAY_SIZE(ipv6fields
),
319 .u
._struct
.fields
= ipv6fields
,
324 enum network_header_types
{
330 static inline unsigned char __get_network_header_type(struct sk_buff
*skb
)
332 if (__has_network_hdr(skb
)) {
333 if (skb
->protocol
== htons(ETH_P_IPV6
))
335 else if (skb
->protocol
== htons(ETH_P_IP
))
337 /* Fallthrough for other header types. */
344 LTTNG_TRACEPOINT_ENUM(net_network_header
,
346 ctf_enum_value("_unknown", NH_NONE
)
347 ctf_enum_value("_ipv4", NH_IPV4
)
348 ctf_enum_value("_ipv6", NH_IPV6
)
352 LTTNG_TRACEPOINT_EVENT(net_dev_xmit
,
354 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
355 TP_PROTO(struct sk_buff
*skb
,
357 struct net_device
*dev
,
358 unsigned int skb_len
),
360 TP_ARGS(skb
, rc
, dev
, skb_len
),
362 TP_PROTO(struct sk_buff
*skb
,
369 ctf_integer_hex(void *, skbaddr
, skb
)
370 ctf_integer(int, rc
, rc
)
371 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
372 ctf_integer(unsigned int, len
, skb_len
)
373 ctf_string(name
, dev
->name
)
375 ctf_integer(unsigned int, len
, skb
->len
)
376 ctf_string(name
, skb
->dev
->name
)
381 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template
,
383 TP_PROTO(struct sk_buff
*skb
),
388 ctf_integer_hex(void *, skbaddr
, skb
)
389 ctf_integer(unsigned int, len
, skb
->len
)
390 ctf_string(name
, skb
->dev
->name
)
391 ctf_enum(net_network_header
, unsigned char,
392 network_header_type
, __get_network_header_type(skb
))
395 .atype
= atype_variant
,
396 .u
.variant
.tag_name
= "network_header_type",
397 .u
.variant
.choices
= network_fields
,
398 .u
.variant
.nr_choices
= ARRAY_SIZE(network_fields
),
402 /* Copy the network header */
403 switch (__get_network_header_type(skb
)) {
406 ctf_array_type(uint8_t, ip_hdr(skb
),
407 sizeof(struct iphdr
))
412 ctf_array_type(uint8_t, ipv6_hdr(skb
),
413 sizeof(struct ipv6hdr
))
417 /* For any other header type, there is nothing to do. */
421 /* Copy the transport header */
422 if (__get_transport_header_type(skb
) == TH_TCP
) {
424 ctf_array_type(uint8_t, tcp_hdr(skb
),
425 sizeof(struct tcphdr
))
427 /* For any other header type, there is nothing to do. */
433 LTTNG_TRACEPOINT_EVENT_INSTANCE(net_dev_template
, net_dev_queue
,
435 TP_PROTO(struct sk_buff
*skb
),
440 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
446 TP_PROTO(struct sk_buff
*skb
),
451 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
457 TP_PROTO(struct sk_buff
*skb
),
461 #endif /* LTTNG_TRACE_NET_H */
463 /* This part must be outside protection */
464 #include <probes/define_trace.h>