Fix: network instrumentation handling of corrupted TCP headers
[lttng-modules.git] / instrumentation / events / lttng-module / net.h
CommitLineData
b283666f
PW
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM net
3
3bc29f0a
MD
4#if !defined(LTTNG_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ)
5#define LTTNG_TRACE_NET_H
b283666f 6
6ec43db8 7#include <probes/lttng-tracepoint-event.h>
b283666f
PW
8#include <linux/skbuff.h>
9#include <linux/netdevice.h>
10#include <linux/ip.h>
e5990fd4
GB
11#include <linux/ipv6.h>
12#include <linux/tcp.h>
4a7363f7 13#include <linux/version.h>
e5990fd4
GB
14#include <lttng-endian.h>
15#include <net/sock.h>
16
17#ifndef ONCE_LTTNG_NET_H
18#define ONCE_LTTNG_NET_H
19
20static inline unsigned char __has_network_hdr(struct sk_buff *skb)
21{
22 /*
aa900596
MD
23 * If the header is not set yet, the network header will point
24 * to the head.
e5990fd4
GB
25 */
26 return skb_network_header(skb) != skb->head;
27}
28
29static struct lttng_event_field emptyfields[] = {
30};
31
9cf9736a
GB
32/* Structures for transport headers. */
33
34static struct lttng_event_field tcpfields[] = {
35 [0] = {
36 .name = "source_port",
aa900596
MD
37 .type = __type_integer(uint16_t, 0, 0, 0,
38 __BIG_ENDIAN, 10, none),
9cf9736a
GB
39 },
40 [1] = {
41 .name = "dest_port",
aa900596
MD
42 .type = __type_integer(uint16_t, 0, 0, 0,
43 __BIG_ENDIAN, 10, none),
9cf9736a
GB
44 },
45 [2] = {
46 .name = "seq",
aa900596
MD
47 .type = __type_integer(uint32_t, 0, 0, 0,
48 __BIG_ENDIAN, 10, none),
9cf9736a
GB
49 },
50 [3] = {
51 .name = "ack_seq",
aa900596
MD
52 .type = __type_integer(uint32_t, 0, 0, 0,
53 __BIG_ENDIAN, 10, none),
9cf9736a
GB
54 },
55 [4] = {
56 .name = "data_offset",
aa900596
MD
57 .type = __type_integer(uint8_t, 4, 4, 0,
58 __BIG_ENDIAN, 10, none),
9cf9736a
GB
59 },
60 [5] = {
61 .name = "reserved",
aa900596
MD
62 .type = __type_integer(uint8_t, 3, 1, 0,
63 __BIG_ENDIAN, 10, none),
9cf9736a
GB
64 },
65 [6] = {
66 .name = "flags",
aa900596
MD
67 .type = __type_integer(uint8_t, 9, 1, 0,
68 __BIG_ENDIAN, 16, none),
9cf9736a
GB
69 },
70 [7] = {
71 .name = "window_size",
aa900596
MD
72 .type = __type_integer(uint16_t, 0, 0, 0,
73 __BIG_ENDIAN, 10, none),
9cf9736a
GB
74 },
75 [8] = {
76 .name = "checksum",
aa900596
MD
77 .type = __type_integer(uint16_t, 0, 0, 0,
78 __BIG_ENDIAN, 16, none),
9cf9736a
GB
79 },
80 [9] = {
81 .name = "urg_ptr",
aa900596
MD
82 .type = __type_integer(uint16_t, 0, 0, 0,
83 __BIG_ENDIAN, 10, none),
9cf9736a
GB
84 },
85};
86
87static struct lttng_event_field transport_fields[] = {
88 [0] = {
89 .name = "unknown",
90 .type = {
91 .atype = atype_struct,
92 .u._struct.nr_fields = ARRAY_SIZE(emptyfields),
93 .u._struct.fields = emptyfields,
94 },
95 },
96 [1] = {
97 .name = "tcp",
98 .type = {
99 .atype = atype_struct,
100 .u._struct.nr_fields = ARRAY_SIZE(tcpfields),
101 .u._struct.fields = tcpfields,
102 },
103 },
104};
105
106enum transport_header_types {
0910ab71
MD
107 TH_NONE = 0,
108 TH_TCP = 1,
9cf9736a
GB
109};
110
0910ab71 111static inline enum transport_header_types __get_transport_header_type(struct sk_buff *skb)
9cf9736a
GB
112{
113 if (__has_network_hdr(skb)) {
114 /*
aa900596
MD
115 * When both transport and network headers are set,
116 * transport header is greater than network header,
117 * otherwise it points to head.
9cf9736a
GB
118 */
119 if (skb->transport_header > skb->network_header) {
120 /*
aa900596
MD
121 * Get the transport protocol from the network
122 * header's data. This method works both for
123 * sent and received packets.
9cf9736a
GB
124 */
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))
129 return TH_TCP;
130 }
131 /* Fallthrough for other cases where header is not TCP. */
132 }
133 return TH_NONE;
134}
135
136static struct lttng_enum_entry transport_enum_entries[] = {
137 [0] = {
0910ab71
MD
138 .start = { .value = TH_NONE, .signedness = 0, },
139 .end = { .value = TH_NONE, .signedness = 0, },
9cf9736a
GB
140 .string = "_unknown",
141 },
142 [1] = {
0910ab71
MD
143 .start = { .value = TH_TCP, .signedness = 0, },
144 .end = { .value = TH_TCP, .signedness = 0, },
9cf9736a
GB
145 .string = "_tcp",
146 },
9cf9736a
GB
147};
148
149static 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),
153};
154
e5990fd4
GB
155/* Structures for network headers. */
156
157static struct lttng_event_field ipv4fields[] = {
158 [0] = {
159 .name = "version",
aa900596
MD
160 .type = __type_integer(uint8_t, 4, 4, 0,
161 __BIG_ENDIAN, 10, none),
e5990fd4
GB
162 },
163 [1] = {
164 .name = "ihl",
aa900596
MD
165 .type = __type_integer(uint8_t, 4, 4, 0,
166 __BIG_ENDIAN, 10, none),
e5990fd4
GB
167 },
168 [2] = {
169 .name = "tos",
aa900596
MD
170 .type = __type_integer(uint8_t, 0, 0, 0,
171 __BIG_ENDIAN, 10, none),
e5990fd4
GB
172 },
173 [3] = {
174 .name = "tot_len",
aa900596
MD
175 .type = __type_integer(uint16_t, 0, 0, 0,
176 __BIG_ENDIAN, 10, none),
e5990fd4
GB
177 },
178 [4] = {
179 .name = "id",
aa900596
MD
180 .type = __type_integer(uint16_t, 0, 0, 0,
181 __BIG_ENDIAN, 16, none),
e5990fd4
GB
182 },
183 [5] = {
184 .name = "frag_off",
aa900596
MD
185 .type = __type_integer(uint16_t, 0, 0, 0,
186 __BIG_ENDIAN, 10, none),
e5990fd4
GB
187 },
188 [6] = {
189 .name = "ttl",
aa900596
MD
190 .type = __type_integer(uint8_t, 0, 0, 0,
191 __BIG_ENDIAN, 10, none),
e5990fd4
GB
192 },
193 [7] = {
194 .name = "protocol",
9cf9736a
GB
195 .type = {
196 .atype = atype_enum,
197 .u.basic.enumeration.desc = &transport_header_type,
198 .u.basic.enumeration.container_type = {
199 .size = 8,
200 .alignment = 8,
201 .signedness = 0,
aa900596
MD
202 .reverse_byte_order =
203 __BIG_ENDIAN != __BYTE_ORDER,
9cf9736a
GB
204 .base = 10,
205 .encoding = lttng_encode_none,
206 },
207 },
e5990fd4
GB
208 },
209 [8] = {
210 .name = "checksum",
aa900596
MD
211 .type = __type_integer(uint16_t, 0, 0, 0,
212 __BIG_ENDIAN, 16, none),
e5990fd4
GB
213 },
214 [9] = {
215 .name = "saddr",
216 .type = {
217 .atype = atype_array,
aa900596
MD
218 .u.array.elem_type =
219 __type_integer(uint8_t, 0, 0, 0,
220 __BIG_ENDIAN, 10, none),
e5990fd4
GB
221 .u.array.length = 4,
222 .u.array.elem_alignment = lttng_alignof(uint8_t),
223 },
224 },
225 [10] = {
226 .name = "daddr",
227 .type = {
228 .atype = atype_array,
aa900596
MD
229 .u.array.elem_type =
230 __type_integer(uint8_t, 0, 0, 0,
231 __BIG_ENDIAN, 10, none),
e5990fd4
GB
232 .u.array.length = 4,
233 .u.array.elem_alignment = lttng_alignof(uint8_t),
234 },
235 },
9cf9736a 236 [11] = {
0910ab71
MD
237 .name = "transport_header_type",
238 .type = {
239 .atype = atype_enum,
240 .u.basic.enumeration.desc = &transport_header_type,
241 .u.basic.enumeration.container_type = {
242 .size = 8,
243 .alignment = 8,
244 .signedness = 0,
245 .reverse_byte_order = 0,
246 .base = 10,
247 .encoding = lttng_encode_none,
248 },
249 },
250 },
251 [12] = {
9cf9736a
GB
252 .name = "transport_header",
253 .type = {
254 .atype = atype_variant,
0910ab71 255 .u.variant.tag_name = "transport_header_type",
9cf9736a
GB
256 .u.variant.choices = transport_fields,
257 .u.variant.nr_choices = ARRAY_SIZE(transport_fields),
258 },
259 },
e5990fd4
GB
260};
261
262static struct lttng_event_field ipv6fields[] = {
263 [0] = {
264 .name = "version",
aa900596
MD
265 .type = __type_integer(uint8_t, 4, 4, 0,
266 __BIG_ENDIAN, 10, none),
e5990fd4
GB
267 },
268 [1] = {
269 .name = "prio",
aa900596
MD
270 .type = __type_integer(uint8_t, 4, 4, 0,
271 __BIG_ENDIAN, 10, none),
e5990fd4
GB
272 },
273 [2] = {
274 .name = "flow_lbl",
275 .type = {
276 .atype = atype_array,
aa900596
MD
277 .u.array.elem_type =
278 __type_integer(uint8_t, 0, 0, 0,
279 __BIG_ENDIAN, 16, none),
e5990fd4
GB
280 .u.array.length = 3,
281 .u.array.elem_alignment = lttng_alignof(uint8_t),
282 },
283 },
284 [3] = {
285 .name = "payload_len",
aa900596
MD
286 .type = __type_integer(uint16_t, 0, 0, 0,
287 __BIG_ENDIAN, 10, none),
e5990fd4
GB
288 },
289 [4] = {
290 .name = "nexthdr",
9cf9736a
GB
291 .type = {
292 .atype = atype_enum,
293 .u.basic.enumeration.desc = &transport_header_type,
294 .u.basic.enumeration.container_type = {
295 .size = 8,
296 .alignment = 8,
297 .signedness = 0,
aa900596
MD
298 .reverse_byte_order =
299 __BIG_ENDIAN != __BYTE_ORDER,
9cf9736a
GB
300 .base = 10,
301 .encoding = lttng_encode_none,
302 },
303 },
e5990fd4
GB
304 },
305 [5] = {
306 .name = "hop_limit",
aa900596
MD
307 .type = __type_integer(uint8_t, 0, 0, 0,
308 __BIG_ENDIAN, 10, none),
e5990fd4
GB
309 },
310 [6] = {
311 .name = "saddr",
312 .type = {
313 .atype = atype_array,
aa900596
MD
314 .u.array.elem_type =
315 __type_integer(uint16_t, 0, 0, 0,
316 __BIG_ENDIAN, 16, none),
e5990fd4
GB
317 .u.array.length = 8,
318 .u.array.elem_alignment = lttng_alignof(uint16_t),
319 },
320 },
321 [7] = {
322 .name = "daddr",
323 .type = {
324 .atype = atype_array,
aa900596
MD
325 .u.array.elem_type =
326 __type_integer(uint16_t, 0, 0, 0,
327 __BIG_ENDIAN, 16, none),
e5990fd4
GB
328 .u.array.length = 8,
329 .u.array.elem_alignment = lttng_alignof(uint16_t),
330 },
331 },
9cf9736a 332 [8] = {
0910ab71
MD
333 .name = "transport_header_type",
334 .type = {
335 .atype = atype_enum,
336 .u.basic.enumeration.desc = &transport_header_type,
337 .u.basic.enumeration.container_type = {
338 .size = 8,
339 .alignment = 8,
340 .signedness = 0,
341 .reverse_byte_order = 0,
342 .base = 10,
343 .encoding = lttng_encode_none,
344 },
345 },
346 },
347 [9] = {
9cf9736a
GB
348 .name = "transport_header",
349 .type = {
350 .atype = atype_variant,
0910ab71 351 .u.variant.tag_name = "transport_header_type",
9cf9736a
GB
352 .u.variant.choices = transport_fields,
353 .u.variant.nr_choices = ARRAY_SIZE(transport_fields),
354 },
355 },
e5990fd4
GB
356};
357
358static struct lttng_event_field network_fields[] = {
359 [0] = {
360 .name = "unknown",
361 .type = {
362 .atype = atype_struct,
363 .u._struct.nr_fields = 0,
364 .u._struct.fields = emptyfields,
365 },
366 },
367 [1] = {
368 .name = "ipv4",
369 .type = {
370 .atype = atype_struct,
371 .u._struct.nr_fields = ARRAY_SIZE(ipv4fields),
372 .u._struct.fields = ipv4fields,
373 },
374 },
375 [2] = {
376 .name = "ipv6",
377 .type = {
378 .atype = atype_struct,
379 .u._struct.nr_fields = ARRAY_SIZE(ipv6fields),
380 .u._struct.fields = ipv6fields,
381 },
382 },
383};
384
385enum network_header_types {
386 NH_NONE,
387 NH_IPV4,
388 NH_IPV6,
389};
390
391static inline unsigned char __get_network_header_type(struct sk_buff *skb)
392{
393 if (__has_network_hdr(skb)) {
394 if (skb->protocol == htons(ETH_P_IPV6))
395 return NH_IPV6;
396 else if (skb->protocol == htons(ETH_P_IP))
397 return NH_IPV4;
398 /* Fallthrough for other header types. */
399 }
400 return NH_NONE;
401}
402
403#endif
404
405LTTNG_TRACEPOINT_ENUM(net_network_header,
406 TP_ENUM_VALUES(
407 ctf_enum_value("_unknown", NH_NONE)
408 ctf_enum_value("_ipv4", NH_IPV4)
409 ctf_enum_value("_ipv6", NH_IPV6)
410 )
411)
b283666f 412
3bc29f0a 413LTTNG_TRACEPOINT_EVENT(net_dev_xmit,
b283666f 414
f95480cf 415#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
b283666f
PW
416 TP_PROTO(struct sk_buff *skb,
417 int rc,
418 struct net_device *dev,
419 unsigned int skb_len),
420
421 TP_ARGS(skb, rc, dev, skb_len),
4a7363f7
PW
422#else
423 TP_PROTO(struct sk_buff *skb,
424 int rc),
aa900596 425
4a7363f7
PW
426 TP_ARGS(skb, rc),
427#endif
b283666f 428
f127e61e 429 TP_FIELDS(
fa91fcac 430 ctf_integer_hex(void *, skbaddr, skb)
f127e61e 431 ctf_integer(int, rc, rc)
f95480cf 432#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
974c0969 433 ctf_integer(unsigned int, len, skb_len)
f127e61e 434 ctf_string(name, dev->name)
4a7363f7 435#else
974c0969 436 ctf_integer(unsigned int, len, skb->len)
f127e61e 437 ctf_string(name, skb->dev->name)
4a7363f7 438#endif
f127e61e 439 )
b283666f
PW
440)
441
3bc29f0a 442LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template,
b283666f
PW
443
444 TP_PROTO(struct sk_buff *skb),
445
446 TP_ARGS(skb),
447
f127e61e 448 TP_FIELDS(
fa91fcac 449 ctf_integer_hex(void *, skbaddr, skb)
f127e61e
MD
450 ctf_integer(unsigned int, len, skb->len)
451 ctf_string(name, skb->dev->name)
e5990fd4
GB
452 ctf_enum(net_network_header, unsigned char,
453 network_header_type, __get_network_header_type(skb))
454 ctf_custom_field(
455 ctf_custom_type(
456 .atype = atype_variant,
457 .u.variant.tag_name = "network_header_type",
458 .u.variant.choices = network_fields,
aa900596
MD
459 .u.variant.nr_choices =
460 ARRAY_SIZE(network_fields),
e5990fd4
GB
461 ),
462 network_header,
463 ctf_custom_code(
0910ab71
MD
464 bool has_network_header = false;
465
aa900596 466 /* Copy the network header. */
e5990fd4
GB
467 switch (__get_network_header_type(skb)) {
468 case NH_IPV4: {
469 ctf_align(uint16_t)
470 ctf_array_type(uint8_t, ip_hdr(skb),
471 sizeof(struct iphdr))
0910ab71 472 has_network_header = true;
e5990fd4
GB
473 break;
474 }
475 case NH_IPV6: {
476 ctf_align(uint16_t)
477 ctf_array_type(uint8_t, ipv6_hdr(skb),
478 sizeof(struct ipv6hdr))
0910ab71 479 has_network_header = true;
e5990fd4
GB
480 break;
481 }
482 default:
aa900596
MD
483 /*
484 * For any other network header
485 * type, there is nothing to do.
486 */
e5990fd4
GB
487 break;
488 }
9cf9736a 489
0910ab71
MD
490 if (has_network_header) {
491 enum transport_header_types th_type =
492 __get_transport_header_type(skb);
493
494 /* Transport header type field. */
495 ctf_integer_type(unsigned char, th_type)
496
497 /* Copy the transport header. */
498 if (th_type == TH_TCP) {
499 ctf_align(uint32_t)
500 ctf_array_type(uint8_t, tcp_hdr(skb),
501 sizeof(struct tcphdr))
502 }
503 /*
504 * For any other transport header type,
505 * there is nothing to do.
506 */
9cf9736a 507 }
e5990fd4
GB
508 )
509 )
f127e61e 510 )
b283666f
PW
511)
512
3bc29f0a 513LTTNG_TRACEPOINT_EVENT_INSTANCE(net_dev_template, net_dev_queue,
b283666f
PW
514
515 TP_PROTO(struct sk_buff *skb),
516
517 TP_ARGS(skb)
518)
519
b7f5408a
MD
520LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template,
521
522 netif_receive_skb,
523
524 net_if_receive_skb,
b283666f
PW
525
526 TP_PROTO(struct sk_buff *skb),
527
528 TP_ARGS(skb)
529)
530
b7f5408a
MD
531LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template,
532
533 netif_rx,
534
535 net_if_rx,
b283666f
PW
536
537 TP_PROTO(struct sk_buff *skb),
538
539 TP_ARGS(skb)
540)
3bc29f0a 541#endif /* LTTNG_TRACE_NET_H */
b283666f
PW
542
543/* This part must be outside protection */
6ec43db8 544#include <probes/define_trace.h>
This page took 0.054089 seconds and 4 git commands to generate.