Commit | Line | Data |
---|---|---|
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 | ||
20 | static 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 | ||
29 | static struct lttng_event_field emptyfields[] = { | |
30 | }; | |
31 | ||
32 | /* Structures for network headers. */ | |
33 | ||
34 | static 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 | ||
91 | static 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 | ||
141 | static 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 | ||
168 | enum network_header_types { | |
169 | NH_NONE, | |
170 | NH_IPV4, | |
171 | NH_IPV6, | |
172 | }; | |
173 | ||
174 | static 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 | ||
188 | LTTNG_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 | 196 | LTTNG_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 | 225 | LTTNG_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 | 268 | LTTNG_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 |
275 | LTTNG_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 |
286 | LTTNG_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> |