1 /* SPDX-License-Identifier: GPL-2.0-only */
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 <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 <linux/udp.h>
15 #include <linux/icmp.h>
16 #include <lttng/kernel-version.h>
17 #include <lttng/endian.h>
20 #ifndef ONCE_LTTNG_NET_H
21 #define ONCE_LTTNG_NET_H
23 static inline unsigned char __has_network_hdr(struct sk_buff
*skb
)
26 * If the header is not set yet, the network header will point
29 return skb_network_header(skb
) != skb
->head
;
32 enum transport_header_types
{
39 static inline enum transport_header_types
__get_transport_header_type_ip(struct sk_buff
*skb
)
41 switch (ip_hdr(skb
)->protocol
) {
52 static inline enum transport_header_types
__get_transport_header_type_ipv6(struct sk_buff
*skb
)
54 switch (ipv6_hdr(skb
)->nexthdr
) {
65 static inline enum transport_header_types
__get_transport_header_type(struct sk_buff
*skb
)
67 if (__has_network_hdr(skb
)) {
69 * When both transport and network headers are set,
70 * transport header is greater than network header,
71 * otherwise it points to head.
73 if (skb
->transport_header
> skb
->network_header
) {
75 * Get the transport protocol from the network
76 * header's data. This method works both for
77 * sent and received packets.
79 if (skb
->protocol
== htons(ETH_P_IP
)) {
80 return __get_transport_header_type_ip(skb
);
81 } else if(skb
->protocol
== htons(ETH_P_IPV6
)) {
82 return __get_transport_header_type_ipv6(skb
);
85 /* Fallthrough for other cases where header is not recognized. */
90 enum network_header_types
{
96 static inline unsigned char __get_network_header_type(struct sk_buff
*skb
)
98 if (__has_network_hdr(skb
)) {
99 if (skb
->protocol
== htons(ETH_P_IPV6
))
101 else if (skb
->protocol
== htons(ETH_P_IP
))
103 /* Fallthrough for other header types. */
110 #ifdef LTTNG_CREATE_FIELD_METADATA
112 static const struct lttng_kernel_event_field
*emptyfields
[] = {
115 /* Structures for transport headers. */
117 static const struct lttng_kernel_event_field
*tcpfields
[] = {
118 [0] = lttng_kernel_static_event_field("source_port",
119 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
120 false, false, false),
121 [1] = lttng_kernel_static_event_field("dest_port",
122 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
123 false, false, false),
124 [2] = lttng_kernel_static_event_field("seq",
125 lttng_kernel_static_type_integer_from_type(uint32_t, __BIG_ENDIAN
, 10),
126 false, false, false),
127 [3] = lttng_kernel_static_event_field("ack_seq",
128 lttng_kernel_static_type_integer_from_type(uint32_t, __BIG_ENDIAN
, 10),
129 false, false, false),
130 [4] = lttng_kernel_static_event_field("data_offset",
131 lttng_kernel_static_type_integer(4, 4, 0, __BIG_ENDIAN
, 10),
132 false, false, false),
133 [5] = lttng_kernel_static_event_field("reserved",
134 lttng_kernel_static_type_integer(3, 1, 0, __BIG_ENDIAN
, 10),
135 false, false, false),
136 [6] = lttng_kernel_static_event_field("flags",
137 lttng_kernel_static_type_integer(9, 1, 0, __BIG_ENDIAN
, 16),
138 false, false, false),
139 [7] = lttng_kernel_static_event_field("window_size",
140 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
141 false, false, false),
142 [8] = lttng_kernel_static_event_field("checksum",
143 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 16),
144 false, false, false),
145 [9] = lttng_kernel_static_event_field("urg_ptr",
146 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
147 false, false, false),
150 static const struct lttng_kernel_event_field
*udpfields
[] = {
151 [0] = lttng_kernel_static_event_field("source_port",
152 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
153 false, false, false),
154 [1] = lttng_kernel_static_event_field("dest_port",
155 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
156 false, false, false),
157 [2] = lttng_kernel_static_event_field("len",
158 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
159 false, false, false),
160 [3] = lttng_kernel_static_event_field("check",
161 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
162 false, false, false),
165 static const struct lttng_kernel_event_field
*icmpfields
[] = {
166 [0] = lttng_kernel_static_event_field("type",
167 lttng_kernel_static_type_integer_from_type(uint8_t, __BIG_ENDIAN
, 10),
168 false, false, false),
169 [1] = lttng_kernel_static_event_field("code",
170 lttng_kernel_static_type_integer_from_type(uint8_t, __BIG_ENDIAN
, 10),
171 false, false, false),
172 [2] = lttng_kernel_static_event_field("checksum",
173 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
174 false, false, false),
175 [3] = lttng_kernel_static_event_field("gateway",
176 lttng_kernel_static_type_integer_from_type(uint32_t, __BIG_ENDIAN
, 10),
177 false, false, false),
180 static const struct lttng_kernel_event_field
*transport_fields
[] = {
181 [0] = lttng_kernel_static_event_field("unknown",
182 lttng_kernel_static_type_struct(ARRAY_SIZE(emptyfields
), emptyfields
, 0),
184 [1] = lttng_kernel_static_event_field("tcp",
185 lttng_kernel_static_type_struct(ARRAY_SIZE(tcpfields
), tcpfields
, 0),
187 [2] = lttng_kernel_static_event_field("udp",
188 lttng_kernel_static_type_struct(ARRAY_SIZE(udpfields
), udpfields
, 0),
190 [3] = lttng_kernel_static_event_field("icmp",
191 lttng_kernel_static_type_struct(ARRAY_SIZE(icmpfields
), icmpfields
, 0),
195 #endif /* LTTNG_CREATE_FIELD_METADATA */
197 LTTNG_TRACEPOINT_ENUM(proto_transport_header_type
,
199 ctf_enum_range("_unknown", 0, IPPROTO_ICMP
- 1)
200 ctf_enum_value("_icmp", IPPROTO_ICMP
)
201 ctf_enum_range("_unknown", IPPROTO_ICMP
+ 1, IPPROTO_TCP
- 1)
202 ctf_enum_value("_tcp", IPPROTO_TCP
)
203 ctf_enum_range("_unknown", IPPROTO_TCP
+ 1, IPPROTO_UDP
- 1)
204 ctf_enum_value("_udp", IPPROTO_UDP
)
205 ctf_enum_range("_unknown", IPPROTO_UDP
+ 1, 255)
209 LTTNG_TRACEPOINT_ENUM(transport_header_type
,
211 ctf_enum_value("_unknown", TH_NONE
)
212 ctf_enum_value("_tcp", TH_TCP
)
213 ctf_enum_value("_udp", TH_UDP
)
214 ctf_enum_value("_icmp", TH_ICMP
)
218 #ifdef LTTNG_CREATE_FIELD_METADATA
220 /* Structures for network headers. */
222 static const struct lttng_kernel_event_field
*ipv4fields
[] = {
223 [0] = lttng_kernel_static_event_field("version",
224 lttng_kernel_static_type_integer(4, 4, 0, __BIG_ENDIAN
, 10),
225 false, false, false),
226 [1] = lttng_kernel_static_event_field("ihl",
227 lttng_kernel_static_type_integer(4, 4, 0, __BIG_ENDIAN
, 10),
228 false, false, false),
229 [2] = lttng_kernel_static_event_field("tos",
230 lttng_kernel_static_type_integer_from_type(uint8_t, __BIG_ENDIAN
, 10),
231 false, false, false),
232 [3] = lttng_kernel_static_event_field("tot_len",
233 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
234 false, false, false),
235 [4] = lttng_kernel_static_event_field("id",
236 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 16),
237 false, false, false),
238 [5] = lttng_kernel_static_event_field("frag_off",
239 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
240 false, false, false),
241 [6] = lttng_kernel_static_event_field("ttl",
242 lttng_kernel_static_type_integer_from_type(uint8_t, __BIG_ENDIAN
, 10),
243 false, false, false),
244 [7] = lttng_kernel_static_event_field("protocol",
245 lttng_kernel_static_type_enum(&__enum_proto_transport_header_type
,
246 lttng_kernel_static_type_integer_from_type(uint8_t, __BIG_ENDIAN
, 10)),
247 false, false, false),
248 [8] = lttng_kernel_static_event_field("checksum",
249 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 16),
250 false, false, false),
251 [9] = lttng_kernel_static_event_field("saddr",
252 lttng_kernel_static_type_array(4,
253 lttng_kernel_static_type_integer_from_type(uint8_t, __BIG_ENDIAN
, 10),
254 lttng_alignof(uint8_t), none
),
255 false, false, false),
256 [10] = lttng_kernel_static_event_field("daddr",
257 lttng_kernel_static_type_array(4,
258 lttng_kernel_static_type_integer_from_type(uint8_t, __BIG_ENDIAN
, 10),
259 lttng_alignof(uint8_t), none
),
260 false, false, false),
261 [11] = lttng_kernel_static_event_field("transport_header_type",
262 lttng_kernel_static_type_enum(&__enum_transport_header_type
,
263 lttng_kernel_static_type_integer_from_type(uint8_t, __BYTE_ORDER
, 10)),
264 false, false, false),
265 [12] = lttng_kernel_static_event_field("transport_header",
266 lttng_kernel_static_type_variant(ARRAY_SIZE(transport_fields
), transport_fields
,
267 NULL
, 0), /* Previous field as tag. */
268 false, false, false),
271 static const struct lttng_kernel_event_field
*ipv6fields
[] = {
272 [0] = lttng_kernel_static_event_field("version",
273 lttng_kernel_static_type_integer(4, 4, 0, __BIG_ENDIAN
, 10),
274 false, false, false),
275 [1] = lttng_kernel_static_event_field("prio",
276 lttng_kernel_static_type_integer(4, 4, 0, __BIG_ENDIAN
, 10),
277 false, false, false),
278 [2] = lttng_kernel_static_event_field("flow_lbl",
279 lttng_kernel_static_type_array(3, lttng_kernel_static_type_integer_from_type(uint8_t, __BIG_ENDIAN
, 16), lttng_alignof(uint8_t), none
),
280 false, false, false),
281 [3] = lttng_kernel_static_event_field("payload_len",
282 lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 10),
283 false, false, false),
284 [4] = lttng_kernel_static_event_field("nexthdr",
285 lttng_kernel_static_type_enum(&__enum_proto_transport_header_type
,
286 lttng_kernel_static_type_integer_from_type(uint8_t, __BIG_ENDIAN
, 10)),
287 false, false, false),
288 [5] = lttng_kernel_static_event_field("hop_limit",
289 lttng_kernel_static_type_integer_from_type(uint8_t, __BIG_ENDIAN
, 10),
290 false, false, false),
291 [6] = lttng_kernel_static_event_field("saddr",
292 lttng_kernel_static_type_array(8, lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 16), lttng_alignof(uint16_t), none
),
293 false, false, false),
294 [7] = lttng_kernel_static_event_field("daddr",
295 lttng_kernel_static_type_array(8, lttng_kernel_static_type_integer_from_type(uint16_t, __BIG_ENDIAN
, 16), lttng_alignof(uint16_t), none
),
296 false, false, false),
297 [8] = lttng_kernel_static_event_field("transport_header_type",
298 lttng_kernel_static_type_enum(&__enum_transport_header_type
,
299 lttng_kernel_static_type_integer_from_type(uint8_t, __BYTE_ORDER
, 10)),
300 false, false, false),
301 [9] = lttng_kernel_static_event_field("transport_header",
302 lttng_kernel_static_type_variant(ARRAY_SIZE(transport_fields
),
303 transport_fields
, NULL
, 0), /* Previous field as tag. */
304 false, false, false),
307 static const struct lttng_kernel_event_field
*network_fields
[] = {
308 [0] = lttng_kernel_static_event_field("unknown",
309 lttng_kernel_static_type_struct(0, emptyfields
, 0),
310 false, false, false),
311 [1] = lttng_kernel_static_event_field("ipv4",
312 lttng_kernel_static_type_struct(ARRAY_SIZE(ipv4fields
), ipv4fields
, 0),
313 false, false, false),
314 [2] = lttng_kernel_static_event_field("ipv6",
315 lttng_kernel_static_type_struct(ARRAY_SIZE(ipv6fields
), ipv6fields
, 0),
316 false, false, false),
319 #endif /* LTTNG_CREATE_FIELD_METADATA */
321 LTTNG_TRACEPOINT_ENUM(net_network_header
,
323 ctf_enum_value("_unknown", NH_NONE
)
324 ctf_enum_value("_ipv4", NH_IPV4
)
325 ctf_enum_value("_ipv6", NH_IPV6
)
329 LTTNG_TRACEPOINT_EVENT(net_dev_xmit
,
331 TP_PROTO(struct sk_buff
*skb
,
333 struct net_device
*dev
,
334 unsigned int skb_len
),
336 TP_ARGS(skb
, rc
, dev
, skb_len
),
339 ctf_integer_hex(void *, skbaddr
, skb
)
340 ctf_integer(int, rc
, rc
)
341 ctf_integer(unsigned int, len
, skb_len
)
342 ctf_string(name
, dev
->name
)
346 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template
,
348 TP_PROTO(struct sk_buff
*skb
),
353 ctf_integer_hex(void *, skbaddr
, skb
)
354 ctf_integer(unsigned int, len
, skb
->len
)
355 ctf_string(name
, skb
->dev
->name
)
356 ctf_enum(net_network_header
, unsigned char,
357 network_header_type
, __get_network_header_type(skb
))
360 lttng_kernel_static_type_variant(ARRAY_SIZE(network_fields
),
361 network_fields
, NULL
, 0) /* Previous field as tag. */
365 bool has_network_header
= false;
367 /* Copy the network header. */
368 switch (__get_network_header_type(skb
)) {
371 ctf_array_type(uint8_t, ip_hdr(skb
),
372 sizeof(struct iphdr
))
373 has_network_header
= true;
378 ctf_array_type(uint8_t, ipv6_hdr(skb
),
379 sizeof(struct ipv6hdr
))
380 has_network_header
= true;
385 * For any other network header
386 * type, there is nothing to do.
391 if (has_network_header
) {
392 enum transport_header_types th_type
=
393 __get_transport_header_type(skb
);
395 /* Transport header type field. */
396 ctf_integer_type(unsigned char, th_type
)
398 /* Copy the transport header. */
402 ctf_array_type(uint8_t, tcp_hdr(skb
),
403 sizeof(struct tcphdr
))
408 ctf_array_type(uint8_t, udp_hdr(skb
),
409 sizeof(struct udphdr
))
414 ctf_array_type(uint8_t, icmp_hdr(skb
),
415 sizeof(struct icmphdr
))
420 * For any other transport header type,
421 * there is nothing to do.
431 LTTNG_TRACEPOINT_EVENT_INSTANCE(net_dev_template
, net_dev_queue
,
433 TP_PROTO(struct sk_buff
*skb
),
438 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
444 TP_PROTO(struct sk_buff
*skb
),
449 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template
,
455 TP_PROTO(struct sk_buff
*skb
),
460 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(3,14,0))
462 /* Trace events for the receive entry points */
463 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_receive_entry_template
,
465 TP_PROTO(const struct sk_buff
*skb
),
470 ctf_integer_hex(const void *, skbaddr
, skb
)
474 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
476 napi_gro_frags_entry
,
478 net_napi_gro_frags_entry
,
480 TP_PROTO(const struct sk_buff
*skb
),
485 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
487 napi_gro_receive_entry
,
489 net_napi_gro_receive_entry
,
491 TP_PROTO(const struct sk_buff
*skb
),
496 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
498 netif_receive_skb_entry
,
500 net_if_receive_skb_entry
,
502 TP_PROTO(const struct sk_buff
*skb
),
507 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
513 TP_PROTO(const struct sk_buff
*skb
),
518 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
524 TP_PROTO(const struct sk_buff
*skb
),
529 #endif /* kernel > 3.14 */
531 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,19,0))
533 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_entry_template
,
535 netif_receive_skb_list_entry
,
537 net_if_receive_skb_list_entry
,
539 TP_PROTO(const struct sk_buff
*skb
),
544 #endif /* kernel > 4.19 */
546 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,0,0))
548 /* Trace events for the receive exit points */
549 LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_receive_exit_template
,
556 ctf_integer(int, ret
, ret
)
560 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
564 net_napi_gro_frags_exit
,
571 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
573 napi_gro_receive_exit
,
575 net_napi_gro_receive_exit
,
582 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
584 netif_receive_skb_exit
,
586 net_if_receive_skb_exit
,
593 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
604 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
615 LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_receive_exit_template
,
617 netif_receive_skb_list_exit
,
619 net_if_receive_skb_list_exit
,
626 #endif /* kernel > 5.0.0 */
628 #endif /* LTTNG_TRACE_NET_H */
630 /* This part must be outside protection */
631 #include <lttng/define_trace.h>