MAINTAINERS: Add entry for Netronix embedded controller
[sfrench/cifs-2.6.git] / tools / testing / selftests / bpf / progs / test_tunnel_kern.c
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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                 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
459 SEC("ip6geneve_set_tunnel")
460 int _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); /* ::11 */
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); /* 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);
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
497 SEC("ip6geneve_get_tunnel")
498 int _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
524 SEC("ipip_set_tunnel")
525 int _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         /* single length check */
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; /* 172.16.1.100 */
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
553 SEC("ipip_get_tunnel")
554 int _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
570 SEC("ipip6_set_tunnel")
571 int _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         /* single length check */
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); /* ::11 */
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
601 SEC("ipip6_get_tunnel")
602 int _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
620 SEC("ip6ip6_set_tunnel")
621 int _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         /* single length check */
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 /* NEXTHDR_ICMP */) {
637                 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
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
650 SEC("ip6ip6_get_tunnel")
651 int _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
669 SEC("xfrm_get_state")
670 int _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
685 char _license[] SEC("license") = "GPL";