WIP FPC-III support
[linux/fpc-iii.git] / tools / testing / selftests / bpf / progs / test_tunnel_kern.c
bloba621b58ab079d57467da21da5947b9246847eba3
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2016 VMware
3 * Copyright (c) 2016 Facebook
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>
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)
29 int _version SEC("version") = 1;
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 */
41 struct vxlan_metadata {
42 __u32 gbp;
45 SEC("gre_set_tunnel")
46 int _gre_set_tunnel(struct __sk_buff *skb)
48 int ret;
49 struct bpf_tunnel_key key;
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;
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;
64 return TC_ACT_OK;
67 SEC("gre_get_tunnel")
68 int _gre_get_tunnel(struct __sk_buff *skb)
70 int ret;
71 struct bpf_tunnel_key key;
72 char fmt[] = "key %d remote ip 0x%x\n";
74 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
75 if (ret < 0) {
76 ERROR(ret);
77 return TC_ACT_SHOT;
80 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
81 return TC_ACT_OK;
84 SEC("ip6gretap_set_tunnel")
85 int _ip6gretap_set_tunnel(struct __sk_buff *skb)
87 struct bpf_tunnel_key key;
88 int ret;
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;
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;
105 return TC_ACT_OK;
108 SEC("ip6gretap_get_tunnel")
109 int _ip6gretap_get_tunnel(struct __sk_buff *skb)
111 char fmt[] = "key %d remote ip6 ::%x label %x\n";
112 struct bpf_tunnel_key key;
113 int ret;
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;
122 bpf_trace_printk(fmt, sizeof(fmt),
123 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
125 return TC_ACT_OK;
128 SEC("erspan_set_tunnel")
129 int _erspan_set_tunnel(struct __sk_buff *skb)
131 struct bpf_tunnel_key key;
132 struct erspan_metadata md;
133 int ret;
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;
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;
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;
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
162 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
163 if (ret < 0) {
164 ERROR(ret);
165 return TC_ACT_SHOT;
168 return TC_ACT_OK;
171 SEC("erspan_get_tunnel")
172 int _erspan_get_tunnel(struct __sk_buff *skb)
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;
180 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
181 if (ret < 0) {
182 ERROR(ret);
183 return TC_ACT_SHOT;
186 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
187 if (ret < 0) {
188 ERROR(ret);
189 return TC_ACT_SHOT;
192 bpf_trace_printk(fmt, sizeof(fmt),
193 key.tunnel_id, key.remote_ipv4, md.version);
195 #ifdef ERSPAN_V1
196 char fmt2[] = "\tindex %x\n";
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";
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
209 return TC_ACT_OK;
212 SEC("ip4ip6erspan_set_tunnel")
213 int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
215 struct bpf_tunnel_key key;
216 struct erspan_metadata md;
217 int ret;
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;
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;
232 __builtin_memset(&md, 0, sizeof(md));
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;
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
247 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
248 if (ret < 0) {
249 ERROR(ret);
250 return TC_ACT_SHOT;
253 return TC_ACT_OK;
256 SEC("ip4ip6erspan_get_tunnel")
257 int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
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;
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;
272 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
273 if (ret < 0) {
274 ERROR(ret);
275 return TC_ACT_SHOT;
278 bpf_trace_printk(fmt, sizeof(fmt),
279 key.tunnel_id, key.remote_ipv4, md.version);
281 #ifdef ERSPAN_V1
282 char fmt2[] = "\tindex %x\n";
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";
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
295 return TC_ACT_OK;
298 SEC("vxlan_set_tunnel")
299 int _vxlan_set_tunnel(struct __sk_buff *skb)
301 int ret;
302 struct bpf_tunnel_key key;
303 struct vxlan_metadata md;
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;
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;
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;
325 return TC_ACT_OK;
328 SEC("vxlan_get_tunnel")
329 int _vxlan_get_tunnel(struct __sk_buff *skb)
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";
336 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
337 if (ret < 0) {
338 ERROR(ret);
339 return TC_ACT_SHOT;
342 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
343 if (ret < 0) {
344 ERROR(ret);
345 return TC_ACT_SHOT;
348 bpf_trace_printk(fmt, sizeof(fmt),
349 key.tunnel_id, key.remote_ipv4, md.gbp);
351 return TC_ACT_OK;
354 SEC("ip6vxlan_set_tunnel")
355 int _ip6vxlan_set_tunnel(struct __sk_buff *skb)
357 struct bpf_tunnel_key key;
358 int ret;
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;
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;
373 return TC_ACT_OK;
376 SEC("ip6vxlan_get_tunnel")
377 int _ip6vxlan_get_tunnel(struct __sk_buff *skb)
379 char fmt[] = "key %d remote ip6 ::%x label %x\n";
380 struct bpf_tunnel_key key;
381 int ret;
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;
390 bpf_trace_printk(fmt, sizeof(fmt),
391 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
393 return TC_ACT_OK;
396 SEC("geneve_set_tunnel")
397 int _geneve_set_tunnel(struct __sk_buff *skb)
399 int ret, ret2;
400 struct bpf_tunnel_key key;
401 struct geneve_opt gopt;
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;
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);
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;
425 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
426 if (ret < 0) {
427 ERROR(ret);
428 return TC_ACT_SHOT;
431 return TC_ACT_OK;
434 SEC("geneve_get_tunnel")
435 int _geneve_get_tunnel(struct __sk_buff *skb)
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";
442 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
443 if (ret < 0) {
444 ERROR(ret);
445 return TC_ACT_SHOT;
448 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
449 if (ret < 0) {
450 ERROR(ret);
451 return TC_ACT_SHOT;
454 bpf_trace_printk(fmt, sizeof(fmt),
455 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
456 return TC_ACT_OK;
459 SEC("ip6geneve_set_tunnel")
460 int _ip6geneve_set_tunnel(struct __sk_buff *skb)
462 struct bpf_tunnel_key key;
463 struct geneve_opt gopt;
464 int ret;
466 __builtin_memset(&key, 0x0, sizeof(key));
467 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
468 key.tunnel_id = 22;
469 key.tunnel_tos = 0;
470 key.tunnel_ttl = 64;
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;
479 __builtin_memset(&gopt, 0x0, sizeof(gopt));
480 gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
481 gopt.type = 0x08;
482 gopt.r1 = 0;
483 gopt.r2 = 0;
484 gopt.r3 = 0;
485 gopt.length = 2; /* 4-byte multiple */
486 *(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef);
488 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
489 if (ret < 0) {
490 ERROR(ret);
491 return TC_ACT_SHOT;
494 return TC_ACT_OK;
497 SEC("ip6geneve_get_tunnel")
498 int _ip6geneve_get_tunnel(struct __sk_buff *skb)
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;
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;
512 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
513 if (ret < 0) {
514 ERROR(ret);
515 return TC_ACT_SHOT;
518 bpf_trace_printk(fmt, sizeof(fmt),
519 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
521 return TC_ACT_OK;
524 SEC("ipip_set_tunnel")
525 int _ipip_set_tunnel(struct __sk_buff *skb)
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;
533 /* single length check */
534 if (data + sizeof(*iph) > data_end) {
535 ERROR(1);
536 return TC_ACT_SHOT;
539 key.tunnel_ttl = 64;
540 if (iph->protocol == IPPROTO_ICMP) {
541 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
544 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
545 if (ret < 0) {
546 ERROR(ret);
547 return TC_ACT_SHOT;
550 return TC_ACT_OK;
553 SEC("ipip_get_tunnel")
554 int _ipip_get_tunnel(struct __sk_buff *skb)
556 int ret;
557 struct bpf_tunnel_key key;
558 char fmt[] = "remote ip 0x%x\n";
560 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
561 if (ret < 0) {
562 ERROR(ret);
563 return TC_ACT_SHOT;
566 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
567 return TC_ACT_OK;
570 SEC("ipip6_set_tunnel")
571 int _ipip6_set_tunnel(struct __sk_buff *skb)
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;
579 /* single length check */
580 if (data + sizeof(*iph) > data_end) {
581 ERROR(1);
582 return TC_ACT_SHOT;
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); /* ::11 */
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;
598 return TC_ACT_OK;
601 SEC("ipip6_get_tunnel")
602 int _ipip6_get_tunnel(struct __sk_buff *skb)
604 int ret;
605 struct bpf_tunnel_key key;
606 char fmt[] = "remote ip6 %x::%x\n";
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;
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;
620 SEC("ip6ip6_set_tunnel")
621 int _ip6ip6_set_tunnel(struct __sk_buff *skb)
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;
629 /* single length check */
630 if (data + sizeof(*iph) > data_end) {
631 ERROR(1);
632 return TC_ACT_SHOT;
635 key.tunnel_ttl = 64;
636 if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
637 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
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;
647 return TC_ACT_OK;
650 SEC("ip6ip6_get_tunnel")
651 int _ip6ip6_get_tunnel(struct __sk_buff *skb)
653 int ret;
654 struct bpf_tunnel_key key;
655 char fmt[] = "remote ip6 %x::%x\n";
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;
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;
669 SEC("xfrm_get_state")
670 int _xfrm_get_state(struct __sk_buff *skb)
672 struct bpf_xfrm_state x;
673 char fmt[] = "reqid %d spi 0x%x remote ip 0x%x\n";
674 int ret;
676 ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
677 if (ret < 0)
678 return TC_ACT_OK;
680 bpf_trace_printk(fmt, sizeof(fmt), x.reqid, bpf_ntohl(x.spi),
681 bpf_ntohl(x.remote_ipv4));
682 return TC_ACT_OK;
685 char _license[] SEC("license") = "GPL";