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