Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[cris-mirror.git] / samples / bpf / tcbpf2_kern.c
blobefdc16d195ff6e889f66104c60003a9801843831
1 /* Copyright (c) 2016 VMware
2 * Copyright (c) 2016 Facebook
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
7 */
8 #define KBUILD_MODNAME "foo"
9 #include <uapi/linux/bpf.h>
10 #include <uapi/linux/if_ether.h>
11 #include <uapi/linux/if_packet.h>
12 #include <uapi/linux/ip.h>
13 #include <uapi/linux/ipv6.h>
14 #include <uapi/linux/in.h>
15 #include <uapi/linux/tcp.h>
16 #include <uapi/linux/filter.h>
17 #include <uapi/linux/pkt_cls.h>
18 #include <uapi/linux/erspan.h>
19 #include <net/ipv6.h>
20 #include "bpf_helpers.h"
21 #include "bpf_endian.h"
23 #define _htonl __builtin_bswap32
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 struct geneve_opt {
30 __be16 opt_class;
31 u8 type;
32 u8 length:5;
33 u8 r3:1;
34 u8 r2:1;
35 u8 r1:1;
36 u8 opt_data[8]; /* hard-coded to 8 byte */
39 struct vxlan_metadata {
40 u32 gbp;
43 SEC("gre_set_tunnel")
44 int _gre_set_tunnel(struct __sk_buff *skb)
46 int ret;
47 struct bpf_tunnel_key key;
49 __builtin_memset(&key, 0x0, sizeof(key));
50 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
51 key.tunnel_id = 2;
52 key.tunnel_tos = 0;
53 key.tunnel_ttl = 64;
55 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
56 if (ret < 0) {
57 ERROR(ret);
58 return TC_ACT_SHOT;
61 return TC_ACT_OK;
64 SEC("gre_get_tunnel")
65 int _gre_get_tunnel(struct __sk_buff *skb)
67 int ret;
68 struct bpf_tunnel_key key;
69 char fmt[] = "key %d remote ip 0x%x\n";
71 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
72 if (ret < 0) {
73 ERROR(ret);
74 return TC_ACT_SHOT;
77 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
78 return TC_ACT_OK;
81 SEC("ip6gretap_set_tunnel")
82 int _ip6gretap_set_tunnel(struct __sk_buff *skb)
84 struct bpf_tunnel_key key;
85 int ret;
87 __builtin_memset(&key, 0x0, sizeof(key));
88 key.remote_ipv6[3] = _htonl(0x11); /* ::11 */
89 key.tunnel_id = 2;
90 key.tunnel_tos = 0;
91 key.tunnel_ttl = 64;
92 key.tunnel_label = 0xabcde;
94 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
95 BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX);
96 if (ret < 0) {
97 ERROR(ret);
98 return TC_ACT_SHOT;
101 return TC_ACT_OK;
104 SEC("ip6gretap_get_tunnel")
105 int _ip6gretap_get_tunnel(struct __sk_buff *skb)
107 char fmt[] = "key %d remote ip6 ::%x label %x\n";
108 struct bpf_tunnel_key key;
109 int ret;
111 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
112 BPF_F_TUNINFO_IPV6);
113 if (ret < 0) {
114 ERROR(ret);
115 return TC_ACT_SHOT;
118 bpf_trace_printk(fmt, sizeof(fmt),
119 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
121 return TC_ACT_OK;
124 SEC("erspan_set_tunnel")
125 int _erspan_set_tunnel(struct __sk_buff *skb)
127 struct bpf_tunnel_key key;
128 struct erspan_metadata md;
129 int ret;
131 __builtin_memset(&key, 0x0, sizeof(key));
132 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
133 key.tunnel_id = 2;
134 key.tunnel_tos = 0;
135 key.tunnel_ttl = 64;
137 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
138 if (ret < 0) {
139 ERROR(ret);
140 return TC_ACT_SHOT;
143 __builtin_memset(&md, 0, sizeof(md));
144 #ifdef ERSPAN_V1
145 md.version = 1;
146 md.u.index = bpf_htonl(123);
147 #else
148 u8 direction = 1;
149 u8 hwid = 7;
151 md.version = 2;
152 md.u.md2.dir = direction;
153 md.u.md2.hwid = hwid & 0xf;
154 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
155 #endif
157 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
158 if (ret < 0) {
159 ERROR(ret);
160 return TC_ACT_SHOT;
163 return TC_ACT_OK;
166 SEC("erspan_get_tunnel")
167 int _erspan_get_tunnel(struct __sk_buff *skb)
169 char fmt[] = "key %d remote ip 0x%x erspan version %d\n";
170 struct bpf_tunnel_key key;
171 struct erspan_metadata md;
172 u32 index;
173 int ret;
175 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
176 if (ret < 0) {
177 ERROR(ret);
178 return TC_ACT_SHOT;
181 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
182 if (ret < 0) {
183 ERROR(ret);
184 return TC_ACT_SHOT;
187 bpf_trace_printk(fmt, sizeof(fmt),
188 key.tunnel_id, key.remote_ipv4, md.version);
190 #ifdef ERSPAN_V1
191 char fmt2[] = "\tindex %x\n";
193 index = bpf_ntohl(md.u.index);
194 bpf_trace_printk(fmt2, sizeof(fmt2), index);
195 #else
196 char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
198 bpf_trace_printk(fmt2, sizeof(fmt2),
199 md.u.md2.dir,
200 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
201 bpf_ntohl(md.u.md2.timestamp));
202 #endif
204 return TC_ACT_OK;
207 SEC("ip4ip6erspan_set_tunnel")
208 int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
210 struct bpf_tunnel_key key;
211 struct erspan_metadata md;
212 int ret;
214 __builtin_memset(&key, 0x0, sizeof(key));
215 key.remote_ipv6[3] = _htonl(0x11);
216 key.tunnel_id = 2;
217 key.tunnel_tos = 0;
218 key.tunnel_ttl = 64;
220 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
221 BPF_F_TUNINFO_IPV6);
222 if (ret < 0) {
223 ERROR(ret);
224 return TC_ACT_SHOT;
227 __builtin_memset(&md, 0, sizeof(md));
229 #ifdef ERSPAN_V1
230 md.u.index = htonl(123);
231 md.version = 1;
232 #else
233 u8 direction = 0;
234 u8 hwid = 17;
236 md.version = 2;
237 md.u.md2.dir = direction;
238 md.u.md2.hwid = hwid & 0xf;
239 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
240 #endif
242 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
243 if (ret < 0) {
244 ERROR(ret);
245 return TC_ACT_SHOT;
248 return TC_ACT_OK;
251 SEC("ip4ip6erspan_get_tunnel")
252 int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
254 char fmt[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
255 struct bpf_tunnel_key key;
256 struct erspan_metadata md;
257 u32 index;
258 int ret;
260 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
261 if (ret < 0) {
262 ERROR(ret);
263 return TC_ACT_SHOT;
266 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
267 if (ret < 0) {
268 ERROR(ret);
269 return TC_ACT_SHOT;
272 bpf_trace_printk(fmt, sizeof(fmt),
273 key.tunnel_id, key.remote_ipv4, md.version);
275 #ifdef ERSPAN_V1
276 char fmt2[] = "\tindex %x\n";
278 index = bpf_ntohl(md.u.index);
279 bpf_trace_printk(fmt2, sizeof(fmt2), index);
280 #else
281 char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
283 bpf_trace_printk(fmt2, sizeof(fmt2),
284 md.u.md2.dir,
285 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
286 bpf_ntohl(md.u.md2.timestamp));
287 #endif
289 return TC_ACT_OK;
292 SEC("vxlan_set_tunnel")
293 int _vxlan_set_tunnel(struct __sk_buff *skb)
295 int ret;
296 struct bpf_tunnel_key key;
297 struct vxlan_metadata md;
299 __builtin_memset(&key, 0x0, sizeof(key));
300 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
301 key.tunnel_id = 2;
302 key.tunnel_tos = 0;
303 key.tunnel_ttl = 64;
305 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
306 if (ret < 0) {
307 ERROR(ret);
308 return TC_ACT_SHOT;
311 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
312 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
313 if (ret < 0) {
314 ERROR(ret);
315 return TC_ACT_SHOT;
318 return TC_ACT_OK;
321 SEC("vxlan_get_tunnel")
322 int _vxlan_get_tunnel(struct __sk_buff *skb)
324 int ret;
325 struct bpf_tunnel_key key;
326 struct vxlan_metadata md;
327 char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
329 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
330 if (ret < 0) {
331 ERROR(ret);
332 return TC_ACT_SHOT;
335 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
336 if (ret < 0) {
337 ERROR(ret);
338 return TC_ACT_SHOT;
341 bpf_trace_printk(fmt, sizeof(fmt),
342 key.tunnel_id, key.remote_ipv4, md.gbp);
344 return TC_ACT_OK;
347 SEC("geneve_set_tunnel")
348 int _geneve_set_tunnel(struct __sk_buff *skb)
350 int ret, ret2;
351 struct bpf_tunnel_key key;
352 struct geneve_opt gopt;
354 __builtin_memset(&key, 0x0, sizeof(key));
355 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
356 key.tunnel_id = 2;
357 key.tunnel_tos = 0;
358 key.tunnel_ttl = 64;
360 __builtin_memset(&gopt, 0x0, sizeof(gopt));
361 gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
362 gopt.type = 0x08;
363 gopt.r1 = 0;
364 gopt.r2 = 0;
365 gopt.r3 = 0;
366 gopt.length = 2; /* 4-byte multiple */
367 *(int *) &gopt.opt_data = 0xdeadbeef;
369 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
370 if (ret < 0) {
371 ERROR(ret);
372 return TC_ACT_SHOT;
375 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
376 if (ret < 0) {
377 ERROR(ret);
378 return TC_ACT_SHOT;
381 return TC_ACT_OK;
384 SEC("geneve_get_tunnel")
385 int _geneve_get_tunnel(struct __sk_buff *skb)
387 int ret;
388 struct bpf_tunnel_key key;
389 struct geneve_opt gopt;
390 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
392 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
393 if (ret < 0) {
394 ERROR(ret);
395 return TC_ACT_SHOT;
398 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
399 if (ret < 0) {
400 ERROR(ret);
401 return TC_ACT_SHOT;
404 bpf_trace_printk(fmt, sizeof(fmt),
405 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
406 return TC_ACT_OK;
409 SEC("ipip_set_tunnel")
410 int _ipip_set_tunnel(struct __sk_buff *skb)
412 struct bpf_tunnel_key key = {};
413 void *data = (void *)(long)skb->data;
414 struct iphdr *iph = data;
415 struct tcphdr *tcp = data + sizeof(*iph);
416 void *data_end = (void *)(long)skb->data_end;
417 int ret;
419 /* single length check */
420 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
421 ERROR(1);
422 return TC_ACT_SHOT;
425 key.tunnel_ttl = 64;
426 if (iph->protocol == IPPROTO_ICMP) {
427 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
428 } else {
429 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
430 return TC_ACT_SHOT;
432 if (tcp->dest == htons(5200))
433 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
434 else if (tcp->dest == htons(5201))
435 key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
436 else
437 return TC_ACT_SHOT;
440 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
441 if (ret < 0) {
442 ERROR(ret);
443 return TC_ACT_SHOT;
446 return TC_ACT_OK;
449 SEC("ipip_get_tunnel")
450 int _ipip_get_tunnel(struct __sk_buff *skb)
452 int ret;
453 struct bpf_tunnel_key key;
454 char fmt[] = "remote ip 0x%x\n";
456 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
457 if (ret < 0) {
458 ERROR(ret);
459 return TC_ACT_SHOT;
462 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
463 return TC_ACT_OK;
466 SEC("ipip6_set_tunnel")
467 int _ipip6_set_tunnel(struct __sk_buff *skb)
469 struct bpf_tunnel_key key = {};
470 void *data = (void *)(long)skb->data;
471 struct iphdr *iph = data;
472 struct tcphdr *tcp = data + sizeof(*iph);
473 void *data_end = (void *)(long)skb->data_end;
474 int ret;
476 /* single length check */
477 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
478 ERROR(1);
479 return TC_ACT_SHOT;
482 key.remote_ipv6[0] = _htonl(0x2401db00);
483 key.tunnel_ttl = 64;
485 if (iph->protocol == IPPROTO_ICMP) {
486 key.remote_ipv6[3] = _htonl(1);
487 } else {
488 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) {
489 ERROR(iph->protocol);
490 return TC_ACT_SHOT;
493 if (tcp->dest == htons(5200)) {
494 key.remote_ipv6[3] = _htonl(1);
495 } else if (tcp->dest == htons(5201)) {
496 key.remote_ipv6[3] = _htonl(2);
497 } else {
498 ERROR(tcp->dest);
499 return TC_ACT_SHOT;
503 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
504 if (ret < 0) {
505 ERROR(ret);
506 return TC_ACT_SHOT;
509 return TC_ACT_OK;
512 SEC("ipip6_get_tunnel")
513 int _ipip6_get_tunnel(struct __sk_buff *skb)
515 int ret;
516 struct bpf_tunnel_key key;
517 char fmt[] = "remote ip6 %x::%x\n";
519 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
520 if (ret < 0) {
521 ERROR(ret);
522 return TC_ACT_SHOT;
525 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
526 _htonl(key.remote_ipv6[3]));
527 return TC_ACT_OK;
530 SEC("ip6ip6_set_tunnel")
531 int _ip6ip6_set_tunnel(struct __sk_buff *skb)
533 struct bpf_tunnel_key key = {};
534 void *data = (void *)(long)skb->data;
535 struct ipv6hdr *iph = data;
536 struct tcphdr *tcp = data + sizeof(*iph);
537 void *data_end = (void *)(long)skb->data_end;
538 int ret;
540 /* single length check */
541 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
542 ERROR(1);
543 return TC_ACT_SHOT;
546 key.remote_ipv6[0] = _htonl(0x2401db00);
547 key.tunnel_ttl = 64;
549 if (iph->nexthdr == NEXTHDR_ICMP) {
550 key.remote_ipv6[3] = _htonl(1);
551 } else {
552 if (iph->nexthdr != NEXTHDR_TCP) {
553 ERROR(iph->nexthdr);
554 return TC_ACT_SHOT;
557 if (tcp->dest == htons(5200)) {
558 key.remote_ipv6[3] = _htonl(1);
559 } else if (tcp->dest == htons(5201)) {
560 key.remote_ipv6[3] = _htonl(2);
561 } else {
562 ERROR(tcp->dest);
563 return TC_ACT_SHOT;
567 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
568 if (ret < 0) {
569 ERROR(ret);
570 return TC_ACT_SHOT;
573 return TC_ACT_OK;
576 SEC("ip6ip6_get_tunnel")
577 int _ip6ip6_get_tunnel(struct __sk_buff *skb)
579 int ret;
580 struct bpf_tunnel_key key;
581 char fmt[] = "remote ip6 %x::%x\n";
583 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
584 if (ret < 0) {
585 ERROR(ret);
586 return TC_ACT_SHOT;
589 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
590 _htonl(key.remote_ipv6[3]));
591 return TC_ACT_OK;
594 char _license[] SEC("license") = "GPL";