1
2
3
4
5
6
7
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
29int _version SEC("version") = 1;
30
31struct 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];
39};
40
41struct vxlan_metadata {
42 __u32 gbp;
43};
44
45SEC("gre_set_tunnel")
46int _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;
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
67SEC("gre_get_tunnel")
68int _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
84SEC("ip6gretap_set_tunnel")
85int _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);
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
108SEC("ip6gretap_get_tunnel")
109int _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
128SEC("erspan_set_tunnel")
129int _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;
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
171SEC("erspan_get_tunnel")
172int _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
212SEC("ip4ip6erspan_set_tunnel")
213int _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
256SEC("ip4ip6erspan_get_tunnel")
257int _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
298SEC("vxlan_set_tunnel")
299int _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;
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;
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
328SEC("vxlan_get_tunnel")
329int _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
354SEC("ip6vxlan_set_tunnel")
355int _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);
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
376SEC("ip6vxlan_get_tunnel")
377int _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
396SEC("geneve_set_tunnel")
397int _geneve_set_tunnel(struct __sk_buff *skb)
398{
399 int ret;
400 struct bpf_tunnel_key key;
401 struct geneve_opt gopt;
402
403 __builtin_memset(&key, 0x0, sizeof(key));
404 key.remote_ipv4 = 0xac100164;
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);
411 gopt.type = 0x08;
412 gopt.r1 = 0;
413 gopt.r2 = 0;
414 gopt.r3 = 0;
415 gopt.length = 2;
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
434SEC("geneve_get_tunnel")
435int _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
457SEC("ip6geneve_set_tunnel")
458int _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);
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);
479 gopt.type = 0x08;
480 gopt.r1 = 0;
481 gopt.r2 = 0;
482 gopt.r3 = 0;
483 gopt.length = 2;
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
495SEC("ip6geneve_get_tunnel")
496int _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
520SEC("ipip_set_tunnel")
521int _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
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;
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
549SEC("ipip_get_tunnel")
550int _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
566SEC("ipip6_set_tunnel")
567int _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
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);
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
597SEC("ipip6_get_tunnel")
598int _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
616SEC("ip6ip6_set_tunnel")
617int _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
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 ) {
633 key.remote_ipv6[3] = bpf_htonl(0x11);
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
646SEC("ip6ip6_get_tunnel")
647int _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
665SEC("xfrm_get_state")
666int _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
681char _license[] SEC("license") = "GPL";
682