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, 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;
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 ERROR(ret);
451 return TC_ACT_SHOT;
452 }
453
454 bpf_trace_printk(fmt, sizeof(fmt),
455 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
456 return TC_ACT_OK;
457}
458
459SEC("ip6geneve_set_tunnel")
460int _ip6geneve_set_tunnel(struct __sk_buff *skb)
461{
462 struct bpf_tunnel_key key;
463 struct geneve_opt gopt;
464 int ret;
465
466 __builtin_memset(&key, 0x0, sizeof(key));
467 key.remote_ipv6[3] = bpf_htonl(0x11);
468 key.tunnel_id = 22;
469 key.tunnel_tos = 0;
470 key.tunnel_ttl = 64;
471
472 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
473 BPF_F_TUNINFO_IPV6);
474 if (ret < 0) {
475 ERROR(ret);
476 return TC_ACT_SHOT;
477 }
478
479 __builtin_memset(&gopt, 0x0, sizeof(gopt));
480 gopt.opt_class = bpf_htons(0x102);
481 gopt.type = 0x08;
482 gopt.r1 = 0;
483 gopt.r2 = 0;
484 gopt.r3 = 0;
485 gopt.length = 2;
486 *(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef);
487
488 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
489 if (ret < 0) {
490 ERROR(ret);
491 return TC_ACT_SHOT;
492 }
493
494 return TC_ACT_OK;
495}
496
497SEC("ip6geneve_get_tunnel")
498int _ip6geneve_get_tunnel(struct __sk_buff *skb)
499{
500 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
501 struct bpf_tunnel_key key;
502 struct geneve_opt gopt;
503 int ret;
504
505 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
506 BPF_F_TUNINFO_IPV6);
507 if (ret < 0) {
508 ERROR(ret);
509 return TC_ACT_SHOT;
510 }
511
512 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
513 if (ret < 0) {
514 ERROR(ret);
515 return TC_ACT_SHOT;
516 }
517
518 bpf_trace_printk(fmt, sizeof(fmt),
519 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
520
521 return TC_ACT_OK;
522}
523
524SEC("ipip_set_tunnel")
525int _ipip_set_tunnel(struct __sk_buff *skb)
526{
527 struct bpf_tunnel_key key = {};
528 void *data = (void *)(long)skb->data;
529 struct iphdr *iph = data;
530 void *data_end = (void *)(long)skb->data_end;
531 int ret;
532
533
534 if (data + sizeof(*iph) > data_end) {
535 ERROR(1);
536 return TC_ACT_SHOT;
537 }
538
539 key.tunnel_ttl = 64;
540 if (iph->protocol == IPPROTO_ICMP) {
541 key.remote_ipv4 = 0xac100164;
542 }
543
544 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
545 if (ret < 0) {
546 ERROR(ret);
547 return TC_ACT_SHOT;
548 }
549
550 return TC_ACT_OK;
551}
552
553SEC("ipip_get_tunnel")
554int _ipip_get_tunnel(struct __sk_buff *skb)
555{
556 int ret;
557 struct bpf_tunnel_key key;
558 char fmt[] = "remote ip 0x%x\n";
559
560 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
561 if (ret < 0) {
562 ERROR(ret);
563 return TC_ACT_SHOT;
564 }
565
566 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
567 return TC_ACT_OK;
568}
569
570SEC("ipip6_set_tunnel")
571int _ipip6_set_tunnel(struct __sk_buff *skb)
572{
573 struct bpf_tunnel_key key = {};
574 void *data = (void *)(long)skb->data;
575 struct iphdr *iph = data;
576 void *data_end = (void *)(long)skb->data_end;
577 int ret;
578
579
580 if (data + sizeof(*iph) > data_end) {
581 ERROR(1);
582 return TC_ACT_SHOT;
583 }
584
585 __builtin_memset(&key, 0x0, sizeof(key));
586 key.tunnel_ttl = 64;
587 if (iph->protocol == IPPROTO_ICMP) {
588 key.remote_ipv6[3] = bpf_htonl(0x11);
589 }
590
591 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
592 BPF_F_TUNINFO_IPV6);
593 if (ret < 0) {
594 ERROR(ret);
595 return TC_ACT_SHOT;
596 }
597
598 return TC_ACT_OK;
599}
600
601SEC("ipip6_get_tunnel")
602int _ipip6_get_tunnel(struct __sk_buff *skb)
603{
604 int ret;
605 struct bpf_tunnel_key key;
606 char fmt[] = "remote ip6 %x::%x\n";
607
608 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
609 BPF_F_TUNINFO_IPV6);
610 if (ret < 0) {
611 ERROR(ret);
612 return TC_ACT_SHOT;
613 }
614
615 bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
616 bpf_htonl(key.remote_ipv6[3]));
617 return TC_ACT_OK;
618}
619
620SEC("ip6ip6_set_tunnel")
621int _ip6ip6_set_tunnel(struct __sk_buff *skb)
622{
623 struct bpf_tunnel_key key = {};
624 void *data = (void *)(long)skb->data;
625 struct ipv6hdr *iph = data;
626 void *data_end = (void *)(long)skb->data_end;
627 int ret;
628
629
630 if (data + sizeof(*iph) > data_end) {
631 ERROR(1);
632 return TC_ACT_SHOT;
633 }
634
635 key.tunnel_ttl = 64;
636 if (iph->nexthdr == 58 ) {
637 key.remote_ipv6[3] = bpf_htonl(0x11);
638 }
639
640 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
641 BPF_F_TUNINFO_IPV6);
642 if (ret < 0) {
643 ERROR(ret);
644 return TC_ACT_SHOT;
645 }
646
647 return TC_ACT_OK;
648}
649
650SEC("ip6ip6_get_tunnel")
651int _ip6ip6_get_tunnel(struct __sk_buff *skb)
652{
653 int ret;
654 struct bpf_tunnel_key key;
655 char fmt[] = "remote ip6 %x::%x\n";
656
657 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
658 BPF_F_TUNINFO_IPV6);
659 if (ret < 0) {
660 ERROR(ret);
661 return TC_ACT_SHOT;
662 }
663
664 bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
665 bpf_htonl(key.remote_ipv6[3]));
666 return TC_ACT_OK;
667}
668
669SEC("xfrm_get_state")
670int _xfrm_get_state(struct __sk_buff *skb)
671{
672 struct bpf_xfrm_state x;
673 char fmt[] = "reqid %d spi 0x%x remote ip 0x%x\n";
674 int ret;
675
676 ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
677 if (ret < 0)
678 return TC_ACT_OK;
679
680 bpf_trace_printk(fmt, sizeof(fmt), x.reqid, bpf_ntohl(x.spi),
681 bpf_ntohl(x.remote_ipv4));
682 return TC_ACT_OK;
683}
684
685char _license[] SEC("license") = "GPL";
686