net: Add IPv4/IPv6 header data to net_* tracepoints
[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 /*
23 * If the header is not set yet,
24 * the network header will point to the head.
25 */
26 return skb_network_header(skb) != skb->head;
27}
28
29static struct lttng_event_field emptyfields[] = {
30};
31
32/* Structures for network headers. */
33
34static struct lttng_event_field ipv4fields[] = {
35 [0] = {
36 .name = "version",
37 .type = __type_integer(uint8_t, 4, 4, 0, __BIG_ENDIAN, 10, none),
38 },
39 [1] = {
40 .name = "ihl",
41 .type = __type_integer(uint8_t, 4, 4, 0, __BIG_ENDIAN, 10, none),
42 },
43 [2] = {
44 .name = "tos",
45 .type = __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN, 10, none),
46 },
47 [3] = {
48 .name = "tot_len",
49 .type = __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN, 10, none),
50 },
51 [4] = {
52 .name = "id",
53 .type = __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN, 16, none),
54 },
55 [5] = {
56 .name = "frag_off",
57 .type = __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN, 10, none),
58 },
59 [6] = {
60 .name = "ttl",
61 .type = __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN, 10, none),
62 },
63 [7] = {
64 .name = "protocol",
65 .type = __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN, 10, none),
66 },
67 [8] = {
68 .name = "checksum",
69 .type = __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN, 16, none),
70 },
71 [9] = {
72 .name = "saddr",
73 .type = {
74 .atype = atype_array,
75 .u.array.elem_type = __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN, 10, none),
76 .u.array.length = 4,
77 .u.array.elem_alignment = lttng_alignof(uint8_t),
78 },
79 },
80 [10] = {
81 .name = "daddr",
82 .type = {
83 .atype = atype_array,
84 .u.array.elem_type = __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN, 10, none),
85 .u.array.length = 4,
86 .u.array.elem_alignment = lttng_alignof(uint8_t),
87 },
88 },
89};
90
91static struct lttng_event_field ipv6fields[] = {
92 [0] = {
93 .name = "version",
94 .type = __type_integer(uint8_t, 4, 4, 0, __BIG_ENDIAN, 10, none),
95 },
96 [1] = {
97 .name = "prio",
98 .type = __type_integer(uint8_t, 4, 4, 0, __BIG_ENDIAN, 10, none),
99 },
100 [2] = {
101 .name = "flow_lbl",
102 .type = {
103 .atype = atype_array,
104 .u.array.elem_type = __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN, 16, none),
105 .u.array.length = 3,
106 .u.array.elem_alignment = lttng_alignof(uint8_t),
107 },
108 },
109 [3] = {
110 .name = "payload_len",
111 .type = __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN, 10, none),
112 },
113 [4] = {
114 .name = "nexthdr",
115 .type = __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN, 10, none),
116 },
117 [5] = {
118 .name = "hop_limit",
119 .type = __type_integer(uint8_t, 0, 0, 0, __BIG_ENDIAN, 10, none),
120 },
121 [6] = {
122 .name = "saddr",
123 .type = {
124 .atype = atype_array,
125 .u.array.elem_type = __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN, 16, none),
126 .u.array.length = 8,
127 .u.array.elem_alignment = lttng_alignof(uint16_t),
128 },
129 },
130 [7] = {
131 .name = "daddr",
132 .type = {
133 .atype = atype_array,
134 .u.array.elem_type = __type_integer(uint16_t, 0, 0, 0, __BIG_ENDIAN, 16, none),
135 .u.array.length = 8,
136 .u.array.elem_alignment = lttng_alignof(uint16_t),
137 },
138 },
139};
140
141static struct lttng_event_field network_fields[] = {
142 [0] = {
143 .name = "unknown",
144 .type = {
145 .atype = atype_struct,
146 .u._struct.nr_fields = 0,
147 .u._struct.fields = emptyfields,
148 },
149 },
150 [1] = {
151 .name = "ipv4",
152 .type = {
153 .atype = atype_struct,
154 .u._struct.nr_fields = ARRAY_SIZE(ipv4fields),
155 .u._struct.fields = ipv4fields,
156 },
157 },
158 [2] = {
159 .name = "ipv6",
160 .type = {
161 .atype = atype_struct,
162 .u._struct.nr_fields = ARRAY_SIZE(ipv6fields),
163 .u._struct.fields = ipv6fields,
164 },
165 },
166};
167
168enum network_header_types {
169 NH_NONE,
170 NH_IPV4,
171 NH_IPV6,
172};
173
174static inline unsigned char __get_network_header_type(struct sk_buff *skb)
175{
176 if (__has_network_hdr(skb)) {
177 if (skb->protocol == htons(ETH_P_IPV6))
178 return NH_IPV6;
179 else if (skb->protocol == htons(ETH_P_IP))
180 return NH_IPV4;
181 /* Fallthrough for other header types. */
182 }
183 return NH_NONE;
184}
185
186#endif
187
188LTTNG_TRACEPOINT_ENUM(net_network_header,
189 TP_ENUM_VALUES(
190 ctf_enum_value("_unknown", NH_NONE)
191 ctf_enum_value("_ipv4", NH_IPV4)
192 ctf_enum_value("_ipv6", NH_IPV6)
193 )
194)
b283666f 195
3bc29f0a 196LTTNG_TRACEPOINT_EVENT(net_dev_xmit,
b283666f 197
f95480cf 198#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
b283666f
PW
199 TP_PROTO(struct sk_buff *skb,
200 int rc,
201 struct net_device *dev,
202 unsigned int skb_len),
203
204 TP_ARGS(skb, rc, dev, skb_len),
4a7363f7
PW
205#else
206 TP_PROTO(struct sk_buff *skb,
207 int rc),
208
209 TP_ARGS(skb, rc),
210#endif
b283666f 211
f127e61e 212 TP_FIELDS(
fa91fcac 213 ctf_integer_hex(void *, skbaddr, skb)
f127e61e 214 ctf_integer(int, rc, rc)
f95480cf 215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40))
974c0969 216 ctf_integer(unsigned int, len, skb_len)
f127e61e 217 ctf_string(name, dev->name)
4a7363f7 218#else
974c0969 219 ctf_integer(unsigned int, len, skb->len)
f127e61e 220 ctf_string(name, skb->dev->name)
4a7363f7 221#endif
f127e61e 222 )
b283666f
PW
223)
224
3bc29f0a 225LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template,
b283666f
PW
226
227 TP_PROTO(struct sk_buff *skb),
228
229 TP_ARGS(skb),
230
f127e61e 231 TP_FIELDS(
fa91fcac 232 ctf_integer_hex(void *, skbaddr, skb)
f127e61e
MD
233 ctf_integer(unsigned int, len, skb->len)
234 ctf_string(name, skb->dev->name)
e5990fd4
GB
235 ctf_enum(net_network_header, unsigned char,
236 network_header_type, __get_network_header_type(skb))
237 ctf_custom_field(
238 ctf_custom_type(
239 .atype = atype_variant,
240 .u.variant.tag_name = "network_header_type",
241 .u.variant.choices = network_fields,
242 .u.variant.nr_choices = ARRAY_SIZE(network_fields),
243 ),
244 network_header,
245 ctf_custom_code(
246 switch (__get_network_header_type(skb)) {
247 case NH_IPV4: {
248 ctf_align(uint16_t)
249 ctf_array_type(uint8_t, ip_hdr(skb),
250 sizeof(struct iphdr))
251 break;
252 }
253 case NH_IPV6: {
254 ctf_align(uint16_t)
255 ctf_array_type(uint8_t, ipv6_hdr(skb),
256 sizeof(struct ipv6hdr))
257 break;
258 }
259 default:
260 /* For any other header type, there is nothing to do. */
261 break;
262 }
263 )
264 )
f127e61e 265 )
b283666f
PW
266)
267
3bc29f0a 268LTTNG_TRACEPOINT_EVENT_INSTANCE(net_dev_template, net_dev_queue,
b283666f
PW
269
270 TP_PROTO(struct sk_buff *skb),
271
272 TP_ARGS(skb)
273)
274
b7f5408a
MD
275LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template,
276
277 netif_receive_skb,
278
279 net_if_receive_skb,
b283666f
PW
280
281 TP_PROTO(struct sk_buff *skb),
282
283 TP_ARGS(skb)
284)
285
b7f5408a
MD
286LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(net_dev_template,
287
288 netif_rx,
289
290 net_if_rx,
b283666f
PW
291
292 TP_PROTO(struct sk_buff *skb),
293
294 TP_ARGS(skb)
295)
3bc29f0a 296#endif /* LTTNG_TRACE_NET_H */
b283666f
PW
297
298/* This part must be outside protection */
6ec43db8 299#include <probes/define_trace.h>
This page took 0.039496 seconds and 4 git commands to generate.