1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2016 VMware
3 * Copyright (c) 2016 Facebook
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
8 */
9 #include <stddef.h>
10 #include <string.h>
11 #include <arpa/inet.h>
12 #include <linux/bpf.h>
13 #include <linux/if_ether.h>
14 #include <linux/if_packet.h>
15 #include <linux/ip.h>
16 #include <linux/ipv6.h>
17 #include <linux/types.h>
18 #include <linux/socket.h>
19 #include <linux/pkt_cls.h>
20 #include <linux/erspan.h>
21 #include <bpf/bpf_helpers.h>
22 #include <bpf/bpf_endian.h>
23
24 #define ERROR(ret) do {\
25 char fmt[] = "ERROR line:%d ret:%d\n";\
26 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
27 } while (0)
28
29 struct geneve_opt {
30 __be16 opt_class;
31 __u8 type;
32 __u8 length:5;
33 __u8 r3:1;
34 __u8 r2:1;
35 __u8 r1:1;
36 __u8 opt_data[8]; /* hard-coded to 8 byte */
37 };
38
39 struct vxlan_metadata {
40 __u32 gbp;
41 };
42
43 SEC("gre_set_tunnel")
_gre_set_tunnel(struct __sk_buff * skb)44 int _gre_set_tunnel(struct __sk_buff *skb)
45 {
46 int ret;
47 struct bpf_tunnel_key key;
48
49 __builtin_memset(&key, 0x0, sizeof(key));
50 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
51 key.tunnel_id = 2;
52 key.tunnel_tos = 0;
53 key.tunnel_ttl = 64;
54
55 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
56 BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER);
57 if (ret < 0) {
58 ERROR(ret);
59 return TC_ACT_SHOT;
60 }
61
62 return TC_ACT_OK;
63 }
64
65 SEC("gre_get_tunnel")
_gre_get_tunnel(struct __sk_buff * skb)66 int _gre_get_tunnel(struct __sk_buff *skb)
67 {
68 int ret;
69 struct bpf_tunnel_key key;
70 char fmt[] = "key %d remote ip 0x%x\n";
71
72 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
73 if (ret < 0) {
74 ERROR(ret);
75 return TC_ACT_SHOT;
76 }
77
78 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
79 return TC_ACT_OK;
80 }
81
82 SEC("ip6gretap_set_tunnel")
_ip6gretap_set_tunnel(struct __sk_buff * skb)83 int _ip6gretap_set_tunnel(struct __sk_buff *skb)
84 {
85 struct bpf_tunnel_key key;
86 int ret;
87
88 __builtin_memset(&key, 0x0, sizeof(key));
89 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
90 key.tunnel_id = 2;
91 key.tunnel_tos = 0;
92 key.tunnel_ttl = 64;
93 key.tunnel_label = 0xabcde;
94
95 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
96 BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
97 BPF_F_SEQ_NUMBER);
98 if (ret < 0) {
99 ERROR(ret);
100 return TC_ACT_SHOT;
101 }
102
103 return TC_ACT_OK;
104 }
105
106 SEC("ip6gretap_get_tunnel")
_ip6gretap_get_tunnel(struct __sk_buff * skb)107 int _ip6gretap_get_tunnel(struct __sk_buff *skb)
108 {
109 char fmt[] = "key %d remote ip6 ::%x label %x\n";
110 struct bpf_tunnel_key key;
111 int ret;
112
113 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
114 BPF_F_TUNINFO_IPV6);
115 if (ret < 0) {
116 ERROR(ret);
117 return TC_ACT_SHOT;
118 }
119
120 bpf_trace_printk(fmt, sizeof(fmt),
121 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
122
123 return TC_ACT_OK;
124 }
125
126 SEC("erspan_set_tunnel")
_erspan_set_tunnel(struct __sk_buff * skb)127 int _erspan_set_tunnel(struct __sk_buff *skb)
128 {
129 struct bpf_tunnel_key key;
130 struct erspan_metadata md;
131 int ret;
132
133 __builtin_memset(&key, 0x0, sizeof(key));
134 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
135 key.tunnel_id = 2;
136 key.tunnel_tos = 0;
137 key.tunnel_ttl = 64;
138
139 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
140 BPF_F_ZERO_CSUM_TX);
141 if (ret < 0) {
142 ERROR(ret);
143 return TC_ACT_SHOT;
144 }
145
146 __builtin_memset(&md, 0, sizeof(md));
147 #ifdef ERSPAN_V1
148 md.version = 1;
149 md.u.index = bpf_htonl(123);
150 #else
151 __u8 direction = 1;
152 __u8 hwid = 7;
153
154 md.version = 2;
155 md.u.md2.dir = direction;
156 md.u.md2.hwid = hwid & 0xf;
157 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
158 #endif
159
160 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
161 if (ret < 0) {
162 ERROR(ret);
163 return TC_ACT_SHOT;
164 }
165
166 return TC_ACT_OK;
167 }
168
169 SEC("erspan_get_tunnel")
_erspan_get_tunnel(struct __sk_buff * skb)170 int _erspan_get_tunnel(struct __sk_buff *skb)
171 {
172 char fmt[] = "key %d remote ip 0x%x erspan version %d\n";
173 struct bpf_tunnel_key key;
174 struct erspan_metadata md;
175 __u32 index;
176 int ret;
177
178 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
179 if (ret < 0) {
180 ERROR(ret);
181 return TC_ACT_SHOT;
182 }
183
184 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
185 if (ret < 0) {
186 ERROR(ret);
187 return TC_ACT_SHOT;
188 }
189
190 bpf_trace_printk(fmt, sizeof(fmt),
191 key.tunnel_id, key.remote_ipv4, md.version);
192
193 #ifdef ERSPAN_V1
194 char fmt2[] = "\tindex %x\n";
195
196 index = bpf_ntohl(md.u.index);
197 bpf_trace_printk(fmt2, sizeof(fmt2), index);
198 #else
199 char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
200
201 bpf_trace_printk(fmt2, sizeof(fmt2),
202 md.u.md2.dir,
203 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
204 bpf_ntohl(md.u.md2.timestamp));
205 #endif
206
207 return TC_ACT_OK;
208 }
209
210 SEC("ip4ip6erspan_set_tunnel")
_ip4ip6erspan_set_tunnel(struct __sk_buff * skb)211 int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
212 {
213 struct bpf_tunnel_key key;
214 struct erspan_metadata md;
215 int ret;
216
217 __builtin_memset(&key, 0x0, sizeof(key));
218 key.remote_ipv6[3] = bpf_htonl(0x11);
219 key.tunnel_id = 2;
220 key.tunnel_tos = 0;
221 key.tunnel_ttl = 64;
222
223 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
224 BPF_F_TUNINFO_IPV6);
225 if (ret < 0) {
226 ERROR(ret);
227 return TC_ACT_SHOT;
228 }
229
230 __builtin_memset(&md, 0, sizeof(md));
231
232 #ifdef ERSPAN_V1
233 md.u.index = bpf_htonl(123);
234 md.version = 1;
235 #else
236 __u8 direction = 0;
237 __u8 hwid = 17;
238
239 md.version = 2;
240 md.u.md2.dir = direction;
241 md.u.md2.hwid = hwid & 0xf;
242 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
243 #endif
244
245 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
246 if (ret < 0) {
247 ERROR(ret);
248 return TC_ACT_SHOT;
249 }
250
251 return TC_ACT_OK;
252 }
253
254 SEC("ip4ip6erspan_get_tunnel")
_ip4ip6erspan_get_tunnel(struct __sk_buff * skb)255 int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
256 {
257 char fmt[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
258 struct bpf_tunnel_key key;
259 struct erspan_metadata md;
260 __u32 index;
261 int ret;
262
263 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
264 BPF_F_TUNINFO_IPV6);
265 if (ret < 0) {
266 ERROR(ret);
267 return TC_ACT_SHOT;
268 }
269
270 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
271 if (ret < 0) {
272 ERROR(ret);
273 return TC_ACT_SHOT;
274 }
275
276 bpf_trace_printk(fmt, sizeof(fmt),
277 key.tunnel_id, key.remote_ipv4, md.version);
278
279 #ifdef ERSPAN_V1
280 char fmt2[] = "\tindex %x\n";
281
282 index = bpf_ntohl(md.u.index);
283 bpf_trace_printk(fmt2, sizeof(fmt2), index);
284 #else
285 char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
286
287 bpf_trace_printk(fmt2, sizeof(fmt2),
288 md.u.md2.dir,
289 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
290 bpf_ntohl(md.u.md2.timestamp));
291 #endif
292
293 return TC_ACT_OK;
294 }
295
296 SEC("vxlan_set_tunnel")
_vxlan_set_tunnel(struct __sk_buff * skb)297 int _vxlan_set_tunnel(struct __sk_buff *skb)
298 {
299 int ret;
300 struct bpf_tunnel_key key;
301 struct vxlan_metadata md;
302
303 __builtin_memset(&key, 0x0, sizeof(key));
304 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
305 key.tunnel_id = 2;
306 key.tunnel_tos = 0;
307 key.tunnel_ttl = 64;
308
309 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
310 BPF_F_ZERO_CSUM_TX);
311 if (ret < 0) {
312 ERROR(ret);
313 return TC_ACT_SHOT;
314 }
315
316 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
317 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
318 if (ret < 0) {
319 ERROR(ret);
320 return TC_ACT_SHOT;
321 }
322
323 return TC_ACT_OK;
324 }
325
326 SEC("vxlan_get_tunnel")
_vxlan_get_tunnel(struct __sk_buff * skb)327 int _vxlan_get_tunnel(struct __sk_buff *skb)
328 {
329 int ret;
330 struct bpf_tunnel_key key;
331 struct vxlan_metadata md;
332 char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
333
334 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
335 if (ret < 0) {
336 ERROR(ret);
337 return TC_ACT_SHOT;
338 }
339
340 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
341 if (ret < 0) {
342 ERROR(ret);
343 return TC_ACT_SHOT;
344 }
345
346 bpf_trace_printk(fmt, sizeof(fmt),
347 key.tunnel_id, key.remote_ipv4, md.gbp);
348
349 return TC_ACT_OK;
350 }
351
352 SEC("ip6vxlan_set_tunnel")
_ip6vxlan_set_tunnel(struct __sk_buff * skb)353 int _ip6vxlan_set_tunnel(struct __sk_buff *skb)
354 {
355 struct bpf_tunnel_key key;
356 int ret;
357
358 __builtin_memset(&key, 0x0, sizeof(key));
359 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
360 key.tunnel_id = 22;
361 key.tunnel_tos = 0;
362 key.tunnel_ttl = 64;
363
364 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
365 BPF_F_TUNINFO_IPV6);
366 if (ret < 0) {
367 ERROR(ret);
368 return TC_ACT_SHOT;
369 }
370
371 return TC_ACT_OK;
372 }
373
374 SEC("ip6vxlan_get_tunnel")
_ip6vxlan_get_tunnel(struct __sk_buff * skb)375 int _ip6vxlan_get_tunnel(struct __sk_buff *skb)
376 {
377 char fmt[] = "key %d remote ip6 ::%x label %x\n";
378 struct bpf_tunnel_key key;
379 int ret;
380
381 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
382 BPF_F_TUNINFO_IPV6);
383 if (ret < 0) {
384 ERROR(ret);
385 return TC_ACT_SHOT;
386 }
387
388 bpf_trace_printk(fmt, sizeof(fmt),
389 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
390
391 return TC_ACT_OK;
392 }
393
394 SEC("geneve_set_tunnel")
_geneve_set_tunnel(struct __sk_buff * skb)395 int _geneve_set_tunnel(struct __sk_buff *skb)
396 {
397 int ret;
398 struct bpf_tunnel_key key;
399 struct geneve_opt gopt;
400
401 __builtin_memset(&key, 0x0, sizeof(key));
402 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
403 key.tunnel_id = 2;
404 key.tunnel_tos = 0;
405 key.tunnel_ttl = 64;
406
407 __builtin_memset(&gopt, 0x0, sizeof(gopt));
408 gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
409 gopt.type = 0x08;
410 gopt.r1 = 0;
411 gopt.r2 = 0;
412 gopt.r3 = 0;
413 gopt.length = 2; /* 4-byte multiple */
414 *(int *) &gopt.opt_data = bpf_htonl(0xdeadbeef);
415
416 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
417 BPF_F_ZERO_CSUM_TX);
418 if (ret < 0) {
419 ERROR(ret);
420 return TC_ACT_SHOT;
421 }
422
423 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
424 if (ret < 0) {
425 ERROR(ret);
426 return TC_ACT_SHOT;
427 }
428
429 return TC_ACT_OK;
430 }
431
432 SEC("geneve_get_tunnel")
_geneve_get_tunnel(struct __sk_buff * skb)433 int _geneve_get_tunnel(struct __sk_buff *skb)
434 {
435 int ret;
436 struct bpf_tunnel_key key;
437 struct geneve_opt gopt;
438 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
439
440 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
441 if (ret < 0) {
442 ERROR(ret);
443 return TC_ACT_SHOT;
444 }
445
446 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
447 if (ret < 0)
448 gopt.opt_class = 0;
449
450 bpf_trace_printk(fmt, sizeof(fmt),
451 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
452 return TC_ACT_OK;
453 }
454
455 SEC("ip6geneve_set_tunnel")
_ip6geneve_set_tunnel(struct __sk_buff * skb)456 int _ip6geneve_set_tunnel(struct __sk_buff *skb)
457 {
458 struct bpf_tunnel_key key;
459 struct geneve_opt gopt;
460 int ret;
461
462 __builtin_memset(&key, 0x0, sizeof(key));
463 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
464 key.tunnel_id = 22;
465 key.tunnel_tos = 0;
466 key.tunnel_ttl = 64;
467
468 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
469 BPF_F_TUNINFO_IPV6);
470 if (ret < 0) {
471 ERROR(ret);
472 return TC_ACT_SHOT;
473 }
474
475 __builtin_memset(&gopt, 0x0, sizeof(gopt));
476 gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
477 gopt.type = 0x08;
478 gopt.r1 = 0;
479 gopt.r2 = 0;
480 gopt.r3 = 0;
481 gopt.length = 2; /* 4-byte multiple */
482 *(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef);
483
484 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
485 if (ret < 0) {
486 ERROR(ret);
487 return TC_ACT_SHOT;
488 }
489
490 return TC_ACT_OK;
491 }
492
493 SEC("ip6geneve_get_tunnel")
_ip6geneve_get_tunnel(struct __sk_buff * skb)494 int _ip6geneve_get_tunnel(struct __sk_buff *skb)
495 {
496 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
497 struct bpf_tunnel_key key;
498 struct geneve_opt gopt;
499 int ret;
500
501 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
502 BPF_F_TUNINFO_IPV6);
503 if (ret < 0) {
504 ERROR(ret);
505 return TC_ACT_SHOT;
506 }
507
508 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
509 if (ret < 0)
510 gopt.opt_class = 0;
511
512 bpf_trace_printk(fmt, sizeof(fmt),
513 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
514
515 return TC_ACT_OK;
516 }
517
518 SEC("ipip_set_tunnel")
_ipip_set_tunnel(struct __sk_buff * skb)519 int _ipip_set_tunnel(struct __sk_buff *skb)
520 {
521 struct bpf_tunnel_key key = {};
522 void *data = (void *)(long)skb->data;
523 struct iphdr *iph = data;
524 void *data_end = (void *)(long)skb->data_end;
525 int ret;
526
527 /* single length check */
528 if (data + sizeof(*iph) > data_end) {
529 ERROR(1);
530 return TC_ACT_SHOT;
531 }
532
533 key.tunnel_ttl = 64;
534 if (iph->protocol == IPPROTO_ICMP) {
535 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
536 }
537
538 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
539 if (ret < 0) {
540 ERROR(ret);
541 return TC_ACT_SHOT;
542 }
543
544 return TC_ACT_OK;
545 }
546
547 SEC("ipip_get_tunnel")
_ipip_get_tunnel(struct __sk_buff * skb)548 int _ipip_get_tunnel(struct __sk_buff *skb)
549 {
550 int ret;
551 struct bpf_tunnel_key key;
552 char fmt[] = "remote ip 0x%x\n";
553
554 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
555 if (ret < 0) {
556 ERROR(ret);
557 return TC_ACT_SHOT;
558 }
559
560 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
561 return TC_ACT_OK;
562 }
563
564 SEC("ipip6_set_tunnel")
_ipip6_set_tunnel(struct __sk_buff * skb)565 int _ipip6_set_tunnel(struct __sk_buff *skb)
566 {
567 struct bpf_tunnel_key key = {};
568 void *data = (void *)(long)skb->data;
569 struct iphdr *iph = data;
570 void *data_end = (void *)(long)skb->data_end;
571 int ret;
572
573 /* single length check */
574 if (data + sizeof(*iph) > data_end) {
575 ERROR(1);
576 return TC_ACT_SHOT;
577 }
578
579 __builtin_memset(&key, 0x0, sizeof(key));
580 key.tunnel_ttl = 64;
581 if (iph->protocol == IPPROTO_ICMP) {
582 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
583 }
584
585 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
586 BPF_F_TUNINFO_IPV6);
587 if (ret < 0) {
588 ERROR(ret);
589 return TC_ACT_SHOT;
590 }
591
592 return TC_ACT_OK;
593 }
594
595 SEC("ipip6_get_tunnel")
_ipip6_get_tunnel(struct __sk_buff * skb)596 int _ipip6_get_tunnel(struct __sk_buff *skb)
597 {
598 int ret;
599 struct bpf_tunnel_key key;
600 char fmt[] = "remote ip6 %x::%x\n";
601
602 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
603 BPF_F_TUNINFO_IPV6);
604 if (ret < 0) {
605 ERROR(ret);
606 return TC_ACT_SHOT;
607 }
608
609 bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
610 bpf_htonl(key.remote_ipv6[3]));
611 return TC_ACT_OK;
612 }
613
614 SEC("ip6ip6_set_tunnel")
_ip6ip6_set_tunnel(struct __sk_buff * skb)615 int _ip6ip6_set_tunnel(struct __sk_buff *skb)
616 {
617 struct bpf_tunnel_key key = {};
618 void *data = (void *)(long)skb->data;
619 struct ipv6hdr *iph = data;
620 void *data_end = (void *)(long)skb->data_end;
621 int ret;
622
623 /* single length check */
624 if (data + sizeof(*iph) > data_end) {
625 ERROR(1);
626 return TC_ACT_SHOT;
627 }
628
629 key.tunnel_ttl = 64;
630 if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
631 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
632 }
633
634 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
635 BPF_F_TUNINFO_IPV6);
636 if (ret < 0) {
637 ERROR(ret);
638 return TC_ACT_SHOT;
639 }
640
641 return TC_ACT_OK;
642 }
643
644 SEC("ip6ip6_get_tunnel")
_ip6ip6_get_tunnel(struct __sk_buff * skb)645 int _ip6ip6_get_tunnel(struct __sk_buff *skb)
646 {
647 int ret;
648 struct bpf_tunnel_key key;
649 char fmt[] = "remote ip6 %x::%x\n";
650
651 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
652 BPF_F_TUNINFO_IPV6);
653 if (ret < 0) {
654 ERROR(ret);
655 return TC_ACT_SHOT;
656 }
657
658 bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
659 bpf_htonl(key.remote_ipv6[3]));
660 return TC_ACT_OK;
661 }
662
663 SEC("xfrm_get_state")
_xfrm_get_state(struct __sk_buff * skb)664 int _xfrm_get_state(struct __sk_buff *skb)
665 {
666 struct bpf_xfrm_state x;
667 char fmt[] = "reqid %d spi 0x%x remote ip 0x%x\n";
668 int ret;
669
670 ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
671 if (ret < 0)
672 return TC_ACT_OK;
673
674 bpf_trace_printk(fmt, sizeof(fmt), x.reqid, bpf_ntohl(x.spi),
675 bpf_ntohl(x.remote_ipv4));
676 return TC_ACT_OK;
677 }
678
679 char _license[] SEC("license") = "GPL";
680