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/if_tunnel.h>
16 #include <linux/ip.h>
17 #include <linux/ipv6.h>
18 #include <linux/icmp.h>
19 #include <linux/types.h>
20 #include <linux/socket.h>
21 #include <linux/pkt_cls.h>
22 #include <linux/erspan.h>
23 #include <linux/udp.h>
24 #include <bpf/bpf_helpers.h>
25 #include <bpf/bpf_endian.h>
26
27 #define log_err(__ret) bpf_printk("ERROR line:%d ret:%d\n", __LINE__, __ret)
28
29 #define VXLAN_UDP_PORT 4789
30
31 /* Only IPv4 address assigned to veth1.
32 * 172.16.1.200
33 */
34 #define ASSIGNED_ADDR_VETH1 0xac1001c8
35
36 struct geneve_opt {
37 __be16 opt_class;
38 __u8 type;
39 __u8 length:5;
40 __u8 r3:1;
41 __u8 r2:1;
42 __u8 r1:1;
43 __u8 opt_data[8]; /* hard-coded to 8 byte */
44 };
45
46 struct vxlanhdr {
47 __be32 vx_flags;
48 __be32 vx_vni;
49 } __attribute__((packed));
50
51 struct vxlan_metadata {
52 __u32 gbp;
53 };
54
55 struct bpf_fou_encap {
56 __be16 sport;
57 __be16 dport;
58 };
59
60 enum bpf_fou_encap_type {
61 FOU_BPF_ENCAP_FOU,
62 FOU_BPF_ENCAP_GUE,
63 };
64
65 int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
66 struct bpf_fou_encap *encap, int type) __ksym;
67 int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
68 struct bpf_fou_encap *encap) __ksym;
69
70 struct {
71 __uint(type, BPF_MAP_TYPE_ARRAY);
72 __uint(max_entries, 1);
73 __type(key, __u32);
74 __type(value, __u32);
75 } local_ip_map SEC(".maps");
76
77 SEC("tc")
gre_set_tunnel(struct __sk_buff * skb)78 int gre_set_tunnel(struct __sk_buff *skb)
79 {
80 int ret;
81 struct bpf_tunnel_key key;
82
83 __builtin_memset(&key, 0x0, sizeof(key));
84 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
85 key.tunnel_id = 2;
86 key.tunnel_tos = 0;
87 key.tunnel_ttl = 64;
88
89 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
90 BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER);
91 if (ret < 0) {
92 log_err(ret);
93 return TC_ACT_SHOT;
94 }
95
96 return TC_ACT_OK;
97 }
98
99 SEC("tc")
gre_set_tunnel_no_key(struct __sk_buff * skb)100 int gre_set_tunnel_no_key(struct __sk_buff *skb)
101 {
102 int ret;
103 struct bpf_tunnel_key key;
104
105 __builtin_memset(&key, 0x0, sizeof(key));
106 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
107 key.tunnel_ttl = 64;
108
109 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
110 BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER |
111 BPF_F_NO_TUNNEL_KEY);
112 if (ret < 0) {
113 log_err(ret);
114 return TC_ACT_SHOT;
115 }
116
117 return TC_ACT_OK;
118 }
119
120 SEC("tc")
gre_get_tunnel(struct __sk_buff * skb)121 int gre_get_tunnel(struct __sk_buff *skb)
122 {
123 int ret;
124 struct bpf_tunnel_key key;
125
126 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
127 if (ret < 0) {
128 log_err(ret);
129 return TC_ACT_SHOT;
130 }
131
132 bpf_printk("key %d remote ip 0x%x\n", key.tunnel_id, key.remote_ipv4);
133 return TC_ACT_OK;
134 }
135
136 SEC("tc")
ip6gretap_set_tunnel(struct __sk_buff * skb)137 int ip6gretap_set_tunnel(struct __sk_buff *skb)
138 {
139 struct bpf_tunnel_key key;
140 int ret;
141
142 __builtin_memset(&key, 0x0, sizeof(key));
143 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
144 key.tunnel_id = 2;
145 key.tunnel_tos = 0;
146 key.tunnel_ttl = 64;
147 key.tunnel_label = 0xabcde;
148
149 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
150 BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
151 BPF_F_SEQ_NUMBER);
152 if (ret < 0) {
153 log_err(ret);
154 return TC_ACT_SHOT;
155 }
156
157 return TC_ACT_OK;
158 }
159
160 SEC("tc")
ip6gretap_get_tunnel(struct __sk_buff * skb)161 int ip6gretap_get_tunnel(struct __sk_buff *skb)
162 {
163 struct bpf_tunnel_key key;
164 int ret;
165
166 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
167 BPF_F_TUNINFO_IPV6);
168 if (ret < 0) {
169 log_err(ret);
170 return TC_ACT_SHOT;
171 }
172
173 bpf_printk("key %d remote ip6 ::%x label %x\n",
174 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
175
176 return TC_ACT_OK;
177 }
178
179 SEC("tc")
erspan_set_tunnel(struct __sk_buff * skb)180 int erspan_set_tunnel(struct __sk_buff *skb)
181 {
182 struct bpf_tunnel_key key;
183 struct erspan_metadata md;
184 int ret;
185
186 __builtin_memset(&key, 0x0, sizeof(key));
187 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
188 key.tunnel_id = 2;
189 key.tunnel_tos = 0;
190 key.tunnel_ttl = 64;
191
192 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
193 BPF_F_ZERO_CSUM_TX);
194 if (ret < 0) {
195 log_err(ret);
196 return TC_ACT_SHOT;
197 }
198
199 __builtin_memset(&md, 0, sizeof(md));
200 #ifdef ERSPAN_V1
201 md.version = 1;
202 md.u.index = bpf_htonl(123);
203 #else
204 __u8 direction = 1;
205 __u8 hwid = 7;
206
207 md.version = 2;
208 md.u.md2.dir = direction;
209 md.u.md2.hwid = hwid & 0xf;
210 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
211 #endif
212
213 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
214 if (ret < 0) {
215 log_err(ret);
216 return TC_ACT_SHOT;
217 }
218
219 return TC_ACT_OK;
220 }
221
222 SEC("tc")
erspan_get_tunnel(struct __sk_buff * skb)223 int erspan_get_tunnel(struct __sk_buff *skb)
224 {
225 struct bpf_tunnel_key key;
226 struct erspan_metadata md;
227 int ret;
228
229 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
230 if (ret < 0) {
231 log_err(ret);
232 return TC_ACT_SHOT;
233 }
234
235 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
236 if (ret < 0) {
237 log_err(ret);
238 return TC_ACT_SHOT;
239 }
240
241 bpf_printk("key %d remote ip 0x%x erspan version %d\n",
242 key.tunnel_id, key.remote_ipv4, md.version);
243
244 #ifdef ERSPAN_V1
245 index = bpf_ntohl(md.u.index);
246 bpf_printk("\tindex %x\n", index);
247 #else
248 bpf_printk("\tdirection %d hwid %x timestamp %u\n",
249 md.u.md2.dir,
250 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
251 bpf_ntohl(md.u.md2.timestamp));
252 #endif
253
254 return TC_ACT_OK;
255 }
256
257 SEC("tc")
ip4ip6erspan_set_tunnel(struct __sk_buff * skb)258 int ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
259 {
260 struct bpf_tunnel_key key;
261 struct erspan_metadata md;
262 int ret;
263
264 __builtin_memset(&key, 0x0, sizeof(key));
265 key.remote_ipv6[3] = bpf_htonl(0x11);
266 key.tunnel_id = 2;
267 key.tunnel_tos = 0;
268 key.tunnel_ttl = 64;
269
270 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
271 BPF_F_TUNINFO_IPV6);
272 if (ret < 0) {
273 log_err(ret);
274 return TC_ACT_SHOT;
275 }
276
277 __builtin_memset(&md, 0, sizeof(md));
278
279 #ifdef ERSPAN_V1
280 md.u.index = bpf_htonl(123);
281 md.version = 1;
282 #else
283 __u8 direction = 0;
284 __u8 hwid = 17;
285
286 md.version = 2;
287 md.u.md2.dir = direction;
288 md.u.md2.hwid = hwid & 0xf;
289 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
290 #endif
291
292 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
293 if (ret < 0) {
294 log_err(ret);
295 return TC_ACT_SHOT;
296 }
297
298 return TC_ACT_OK;
299 }
300
301 SEC("tc")
ip4ip6erspan_get_tunnel(struct __sk_buff * skb)302 int ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
303 {
304 struct bpf_tunnel_key key;
305 struct erspan_metadata md;
306 int ret;
307
308 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
309 BPF_F_TUNINFO_IPV6);
310 if (ret < 0) {
311 log_err(ret);
312 return TC_ACT_SHOT;
313 }
314
315 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
316 if (ret < 0) {
317 log_err(ret);
318 return TC_ACT_SHOT;
319 }
320
321 bpf_printk("ip6erspan get key %d remote ip6 ::%x erspan version %d\n",
322 key.tunnel_id, key.remote_ipv4, md.version);
323
324 #ifdef ERSPAN_V1
325 index = bpf_ntohl(md.u.index);
326 bpf_printk("\tindex %x\n", index);
327 #else
328 bpf_printk("\tdirection %d hwid %x timestamp %u\n",
329 md.u.md2.dir,
330 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
331 bpf_ntohl(md.u.md2.timestamp));
332 #endif
333
334 return TC_ACT_OK;
335 }
336
337 SEC("tc")
vxlan_set_tunnel_dst(struct __sk_buff * skb)338 int vxlan_set_tunnel_dst(struct __sk_buff *skb)
339 {
340 struct bpf_tunnel_key key;
341 struct vxlan_metadata md;
342 __u32 index = 0;
343 __u32 *local_ip = NULL;
344 int ret = 0;
345
346 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
347 if (!local_ip) {
348 log_err(ret);
349 return TC_ACT_SHOT;
350 }
351
352 __builtin_memset(&key, 0x0, sizeof(key));
353 key.local_ipv4 = 0xac100164; /* 172.16.1.100 */
354 key.remote_ipv4 = *local_ip;
355 key.tunnel_id = 2;
356 key.tunnel_tos = 0;
357 key.tunnel_ttl = 64;
358
359 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
360 BPF_F_ZERO_CSUM_TX);
361 if (ret < 0) {
362 log_err(ret);
363 return TC_ACT_SHOT;
364 }
365
366 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
367 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
368 if (ret < 0) {
369 log_err(ret);
370 return TC_ACT_SHOT;
371 }
372
373 return TC_ACT_OK;
374 }
375
376 SEC("tc")
vxlan_set_tunnel_src(struct __sk_buff * skb)377 int vxlan_set_tunnel_src(struct __sk_buff *skb)
378 {
379 struct bpf_tunnel_key key;
380 struct vxlan_metadata md;
381 __u32 index = 0;
382 __u32 *local_ip = NULL;
383 int ret = 0;
384
385 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
386 if (!local_ip) {
387 log_err(ret);
388 return TC_ACT_SHOT;
389 }
390
391 __builtin_memset(&key, 0x0, sizeof(key));
392 key.local_ipv4 = *local_ip;
393 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
394 key.tunnel_id = 2;
395 key.tunnel_tos = 0;
396 key.tunnel_ttl = 64;
397
398 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
399 BPF_F_ZERO_CSUM_TX);
400 if (ret < 0) {
401 log_err(ret);
402 return TC_ACT_SHOT;
403 }
404
405 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
406 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
407 if (ret < 0) {
408 log_err(ret);
409 return TC_ACT_SHOT;
410 }
411
412 return TC_ACT_OK;
413 }
414
415 SEC("tc")
vxlan_get_tunnel_src(struct __sk_buff * skb)416 int vxlan_get_tunnel_src(struct __sk_buff *skb)
417 {
418 int ret;
419 struct bpf_tunnel_key key;
420 struct vxlan_metadata md;
421
422 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
423 BPF_F_TUNINFO_FLAGS);
424 if (ret < 0) {
425 log_err(ret);
426 return TC_ACT_SHOT;
427 }
428
429 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
430 if (ret < 0) {
431 log_err(ret);
432 return TC_ACT_SHOT;
433 }
434
435 if (key.local_ipv4 != ASSIGNED_ADDR_VETH1 || md.gbp != 0x800FF ||
436 !(key.tunnel_flags & TUNNEL_KEY) ||
437 (key.tunnel_flags & TUNNEL_CSUM)) {
438 bpf_printk("vxlan key %d local ip 0x%x remote ip 0x%x gbp 0x%x flags 0x%x\n",
439 key.tunnel_id, key.local_ipv4,
440 key.remote_ipv4, md.gbp,
441 bpf_ntohs(key.tunnel_flags));
442 log_err(ret);
443 return TC_ACT_SHOT;
444 }
445
446 return TC_ACT_OK;
447 }
448
449 SEC("tc")
veth_set_outer_dst(struct __sk_buff * skb)450 int veth_set_outer_dst(struct __sk_buff *skb)
451 {
452 struct ethhdr *eth = (struct ethhdr *)(long)skb->data;
453 __u32 assigned_ip = bpf_htonl(ASSIGNED_ADDR_VETH1);
454 void *data_end = (void *)(long)skb->data_end;
455 struct udphdr *udph;
456 struct iphdr *iph;
457 int ret = 0;
458 __s64 csum;
459
460 if ((void *)eth + sizeof(*eth) > data_end) {
461 log_err(ret);
462 return TC_ACT_SHOT;
463 }
464
465 if (eth->h_proto != bpf_htons(ETH_P_IP))
466 return TC_ACT_OK;
467
468 iph = (struct iphdr *)(eth + 1);
469 if ((void *)iph + sizeof(*iph) > data_end) {
470 log_err(ret);
471 return TC_ACT_SHOT;
472 }
473 if (iph->protocol != IPPROTO_UDP)
474 return TC_ACT_OK;
475
476 udph = (struct udphdr *)(iph + 1);
477 if ((void *)udph + sizeof(*udph) > data_end) {
478 log_err(ret);
479 return TC_ACT_SHOT;
480 }
481 if (udph->dest != bpf_htons(VXLAN_UDP_PORT))
482 return TC_ACT_OK;
483
484 if (iph->daddr != assigned_ip) {
485 csum = bpf_csum_diff(&iph->daddr, sizeof(__u32), &assigned_ip,
486 sizeof(__u32), 0);
487 if (bpf_skb_store_bytes(skb, ETH_HLEN + offsetof(struct iphdr, daddr),
488 &assigned_ip, sizeof(__u32), 0) < 0) {
489 log_err(ret);
490 return TC_ACT_SHOT;
491 }
492 if (bpf_l3_csum_replace(skb, ETH_HLEN + offsetof(struct iphdr, check),
493 0, csum, 0) < 0) {
494 log_err(ret);
495 return TC_ACT_SHOT;
496 }
497 bpf_skb_change_type(skb, PACKET_HOST);
498 }
499 return TC_ACT_OK;
500 }
501
502 SEC("tc")
ip6vxlan_set_tunnel_dst(struct __sk_buff * skb)503 int ip6vxlan_set_tunnel_dst(struct __sk_buff *skb)
504 {
505 struct bpf_tunnel_key key;
506 __u32 index = 0;
507 __u32 *local_ip;
508 int ret = 0;
509
510 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
511 if (!local_ip) {
512 log_err(ret);
513 return TC_ACT_SHOT;
514 }
515
516 __builtin_memset(&key, 0x0, sizeof(key));
517 key.local_ipv6[3] = bpf_htonl(0x11); /* ::11 */
518 key.remote_ipv6[3] = bpf_htonl(*local_ip);
519 key.tunnel_id = 22;
520 key.tunnel_tos = 0;
521 key.tunnel_ttl = 64;
522
523 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
524 BPF_F_TUNINFO_IPV6);
525 if (ret < 0) {
526 log_err(ret);
527 return TC_ACT_SHOT;
528 }
529
530 return TC_ACT_OK;
531 }
532
533 SEC("tc")
ip6vxlan_set_tunnel_src(struct __sk_buff * skb)534 int ip6vxlan_set_tunnel_src(struct __sk_buff *skb)
535 {
536 struct bpf_tunnel_key key;
537 __u32 index = 0;
538 __u32 *local_ip;
539 int ret = 0;
540
541 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
542 if (!local_ip) {
543 log_err(ret);
544 return TC_ACT_SHOT;
545 }
546
547 __builtin_memset(&key, 0x0, sizeof(key));
548 key.local_ipv6[3] = bpf_htonl(*local_ip);
549 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
550 key.tunnel_id = 22;
551 key.tunnel_tos = 0;
552 key.tunnel_ttl = 64;
553
554 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
555 BPF_F_TUNINFO_IPV6);
556 if (ret < 0) {
557 log_err(ret);
558 return TC_ACT_SHOT;
559 }
560
561 return TC_ACT_OK;
562 }
563
564 SEC("tc")
ip6vxlan_get_tunnel_src(struct __sk_buff * skb)565 int ip6vxlan_get_tunnel_src(struct __sk_buff *skb)
566 {
567 struct bpf_tunnel_key key;
568 __u32 index = 0;
569 __u32 *local_ip;
570 int ret = 0;
571
572 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
573 if (!local_ip) {
574 log_err(ret);
575 return TC_ACT_SHOT;
576 }
577
578 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
579 BPF_F_TUNINFO_IPV6 | BPF_F_TUNINFO_FLAGS);
580 if (ret < 0) {
581 log_err(ret);
582 return TC_ACT_SHOT;
583 }
584
585 if (bpf_ntohl(key.local_ipv6[3]) != *local_ip ||
586 !(key.tunnel_flags & TUNNEL_KEY) ||
587 !(key.tunnel_flags & TUNNEL_CSUM)) {
588 bpf_printk("ip6vxlan key %d local ip6 ::%x remote ip6 ::%x label 0x%x flags 0x%x\n",
589 key.tunnel_id, bpf_ntohl(key.local_ipv6[3]),
590 bpf_ntohl(key.remote_ipv6[3]), key.tunnel_label,
591 bpf_ntohs(key.tunnel_flags));
592 bpf_printk("local_ip 0x%x\n", *local_ip);
593 log_err(ret);
594 return TC_ACT_SHOT;
595 }
596
597 return TC_ACT_OK;
598 }
599
600 struct local_geneve_opt {
601 struct geneve_opt gopt;
602 int data;
603 };
604
605 SEC("tc")
geneve_set_tunnel(struct __sk_buff * skb)606 int geneve_set_tunnel(struct __sk_buff *skb)
607 {
608 int ret;
609 struct bpf_tunnel_key key;
610 struct local_geneve_opt local_gopt;
611 struct geneve_opt *gopt = (struct geneve_opt *) &local_gopt;
612
613 __builtin_memset(&key, 0x0, sizeof(key));
614 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
615 key.tunnel_id = 2;
616 key.tunnel_tos = 0;
617 key.tunnel_ttl = 64;
618
619 __builtin_memset(gopt, 0x0, sizeof(local_gopt));
620 gopt->opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
621 gopt->type = 0x08;
622 gopt->r1 = 0;
623 gopt->r2 = 0;
624 gopt->r3 = 0;
625 gopt->length = 2; /* 4-byte multiple */
626 *(int *) &gopt->opt_data = bpf_htonl(0xdeadbeef);
627
628 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
629 BPF_F_ZERO_CSUM_TX);
630 if (ret < 0) {
631 log_err(ret);
632 return TC_ACT_SHOT;
633 }
634
635 ret = bpf_skb_set_tunnel_opt(skb, gopt, sizeof(local_gopt));
636 if (ret < 0) {
637 log_err(ret);
638 return TC_ACT_SHOT;
639 }
640
641 return TC_ACT_OK;
642 }
643
644 SEC("tc")
geneve_get_tunnel(struct __sk_buff * skb)645 int geneve_get_tunnel(struct __sk_buff *skb)
646 {
647 int ret;
648 struct bpf_tunnel_key key;
649 struct geneve_opt gopt;
650
651 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
652 if (ret < 0) {
653 log_err(ret);
654 return TC_ACT_SHOT;
655 }
656
657 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
658 if (ret < 0)
659 gopt.opt_class = 0;
660
661 bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
662 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
663 return TC_ACT_OK;
664 }
665
666 SEC("tc")
ip6geneve_set_tunnel(struct __sk_buff * skb)667 int ip6geneve_set_tunnel(struct __sk_buff *skb)
668 {
669 struct bpf_tunnel_key key;
670 struct local_geneve_opt local_gopt;
671 struct geneve_opt *gopt = (struct geneve_opt *) &local_gopt;
672 int ret;
673
674 __builtin_memset(&key, 0x0, sizeof(key));
675 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
676 key.tunnel_id = 22;
677 key.tunnel_tos = 0;
678 key.tunnel_ttl = 64;
679
680 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
681 BPF_F_TUNINFO_IPV6);
682 if (ret < 0) {
683 log_err(ret);
684 return TC_ACT_SHOT;
685 }
686
687 __builtin_memset(gopt, 0x0, sizeof(local_gopt));
688 gopt->opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
689 gopt->type = 0x08;
690 gopt->r1 = 0;
691 gopt->r2 = 0;
692 gopt->r3 = 0;
693 gopt->length = 2; /* 4-byte multiple */
694 *(int *) &gopt->opt_data = bpf_htonl(0xfeedbeef);
695
696 ret = bpf_skb_set_tunnel_opt(skb, gopt, sizeof(gopt));
697 if (ret < 0) {
698 log_err(ret);
699 return TC_ACT_SHOT;
700 }
701
702 return TC_ACT_OK;
703 }
704
705 SEC("tc")
ip6geneve_get_tunnel(struct __sk_buff * skb)706 int ip6geneve_get_tunnel(struct __sk_buff *skb)
707 {
708 struct bpf_tunnel_key key;
709 struct geneve_opt gopt;
710 int ret;
711
712 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
713 BPF_F_TUNINFO_IPV6);
714 if (ret < 0) {
715 log_err(ret);
716 return TC_ACT_SHOT;
717 }
718
719 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
720 if (ret < 0)
721 gopt.opt_class = 0;
722
723 bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
724 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
725
726 return TC_ACT_OK;
727 }
728
729 SEC("tc")
ipip_set_tunnel(struct __sk_buff * skb)730 int ipip_set_tunnel(struct __sk_buff *skb)
731 {
732 struct bpf_tunnel_key key = {};
733 void *data = (void *)(long)skb->data;
734 struct iphdr *iph = data;
735 void *data_end = (void *)(long)skb->data_end;
736 int ret;
737
738 /* single length check */
739 if (data + sizeof(*iph) > data_end) {
740 log_err(1);
741 return TC_ACT_SHOT;
742 }
743
744 key.tunnel_ttl = 64;
745 if (iph->protocol == IPPROTO_ICMP) {
746 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
747 }
748
749 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
750 if (ret < 0) {
751 log_err(ret);
752 return TC_ACT_SHOT;
753 }
754
755 return TC_ACT_OK;
756 }
757
758 SEC("tc")
ipip_get_tunnel(struct __sk_buff * skb)759 int ipip_get_tunnel(struct __sk_buff *skb)
760 {
761 int ret;
762 struct bpf_tunnel_key key;
763
764 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
765 if (ret < 0) {
766 log_err(ret);
767 return TC_ACT_SHOT;
768 }
769
770 bpf_printk("remote ip 0x%x\n", key.remote_ipv4);
771 return TC_ACT_OK;
772 }
773
774 SEC("tc")
ipip_gue_set_tunnel(struct __sk_buff * skb)775 int ipip_gue_set_tunnel(struct __sk_buff *skb)
776 {
777 struct bpf_tunnel_key key = {};
778 struct bpf_fou_encap encap = {};
779 void *data = (void *)(long)skb->data;
780 struct iphdr *iph = data;
781 void *data_end = (void *)(long)skb->data_end;
782 int ret;
783
784 if (data + sizeof(*iph) > data_end) {
785 log_err(1);
786 return TC_ACT_SHOT;
787 }
788
789 key.tunnel_ttl = 64;
790 if (iph->protocol == IPPROTO_ICMP)
791 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
792
793 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
794 if (ret < 0) {
795 log_err(ret);
796 return TC_ACT_SHOT;
797 }
798
799 encap.sport = 0;
800 encap.dport = bpf_htons(5555);
801
802 ret = bpf_skb_set_fou_encap(skb, &encap, FOU_BPF_ENCAP_GUE);
803 if (ret < 0) {
804 log_err(ret);
805 return TC_ACT_SHOT;
806 }
807
808 return TC_ACT_OK;
809 }
810
811 SEC("tc")
ipip_fou_set_tunnel(struct __sk_buff * skb)812 int ipip_fou_set_tunnel(struct __sk_buff *skb)
813 {
814 struct bpf_tunnel_key key = {};
815 struct bpf_fou_encap encap = {};
816 void *data = (void *)(long)skb->data;
817 struct iphdr *iph = data;
818 void *data_end = (void *)(long)skb->data_end;
819 int ret;
820
821 if (data + sizeof(*iph) > data_end) {
822 log_err(1);
823 return TC_ACT_SHOT;
824 }
825
826 key.tunnel_ttl = 64;
827 if (iph->protocol == IPPROTO_ICMP)
828 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
829
830 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
831 if (ret < 0) {
832 log_err(ret);
833 return TC_ACT_SHOT;
834 }
835
836 encap.sport = 0;
837 encap.dport = bpf_htons(5555);
838
839 ret = bpf_skb_set_fou_encap(skb, &encap, FOU_BPF_ENCAP_FOU);
840 if (ret < 0) {
841 log_err(ret);
842 return TC_ACT_SHOT;
843 }
844
845 return TC_ACT_OK;
846 }
847
848 SEC("tc")
ipip_encap_get_tunnel(struct __sk_buff * skb)849 int ipip_encap_get_tunnel(struct __sk_buff *skb)
850 {
851 int ret;
852 struct bpf_tunnel_key key = {};
853 struct bpf_fou_encap encap = {};
854
855 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
856 if (ret < 0) {
857 log_err(ret);
858 return TC_ACT_SHOT;
859 }
860
861 ret = bpf_skb_get_fou_encap(skb, &encap);
862 if (ret < 0) {
863 log_err(ret);
864 return TC_ACT_SHOT;
865 }
866
867 if (bpf_ntohs(encap.dport) != 5555)
868 return TC_ACT_SHOT;
869
870 bpf_printk("%d remote ip 0x%x, sport %d, dport %d\n", ret,
871 key.remote_ipv4, bpf_ntohs(encap.sport),
872 bpf_ntohs(encap.dport));
873 return TC_ACT_OK;
874 }
875
876 SEC("tc")
ipip6_set_tunnel(struct __sk_buff * skb)877 int ipip6_set_tunnel(struct __sk_buff *skb)
878 {
879 struct bpf_tunnel_key key = {};
880 void *data = (void *)(long)skb->data;
881 struct iphdr *iph = data;
882 void *data_end = (void *)(long)skb->data_end;
883 int ret;
884
885 /* single length check */
886 if (data + sizeof(*iph) > data_end) {
887 log_err(1);
888 return TC_ACT_SHOT;
889 }
890
891 __builtin_memset(&key, 0x0, sizeof(key));
892 key.tunnel_ttl = 64;
893 if (iph->protocol == IPPROTO_ICMP) {
894 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
895 }
896
897 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
898 BPF_F_TUNINFO_IPV6);
899 if (ret < 0) {
900 log_err(ret);
901 return TC_ACT_SHOT;
902 }
903
904 return TC_ACT_OK;
905 }
906
907 SEC("tc")
ipip6_get_tunnel(struct __sk_buff * skb)908 int ipip6_get_tunnel(struct __sk_buff *skb)
909 {
910 int ret;
911 struct bpf_tunnel_key key;
912
913 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
914 BPF_F_TUNINFO_IPV6);
915 if (ret < 0) {
916 log_err(ret);
917 return TC_ACT_SHOT;
918 }
919
920 bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
921 bpf_htonl(key.remote_ipv6[3]));
922 return TC_ACT_OK;
923 }
924
925 SEC("tc")
ip6ip6_set_tunnel(struct __sk_buff * skb)926 int ip6ip6_set_tunnel(struct __sk_buff *skb)
927 {
928 struct bpf_tunnel_key key = {};
929 void *data = (void *)(long)skb->data;
930 struct ipv6hdr *iph = data;
931 void *data_end = (void *)(long)skb->data_end;
932 int ret;
933
934 /* single length check */
935 if (data + sizeof(*iph) > data_end) {
936 log_err(1);
937 return TC_ACT_SHOT;
938 }
939
940 key.tunnel_ttl = 64;
941 if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
942 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
943 }
944
945 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
946 BPF_F_TUNINFO_IPV6);
947 if (ret < 0) {
948 log_err(ret);
949 return TC_ACT_SHOT;
950 }
951
952 return TC_ACT_OK;
953 }
954
955 SEC("tc")
ip6ip6_get_tunnel(struct __sk_buff * skb)956 int ip6ip6_get_tunnel(struct __sk_buff *skb)
957 {
958 int ret;
959 struct bpf_tunnel_key key;
960
961 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
962 BPF_F_TUNINFO_IPV6);
963 if (ret < 0) {
964 log_err(ret);
965 return TC_ACT_SHOT;
966 }
967
968 bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
969 bpf_htonl(key.remote_ipv6[3]));
970 return TC_ACT_OK;
971 }
972
973 SEC("tc")
xfrm_get_state(struct __sk_buff * skb)974 int xfrm_get_state(struct __sk_buff *skb)
975 {
976 struct bpf_xfrm_state x;
977 int ret;
978
979 ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
980 if (ret < 0)
981 return TC_ACT_OK;
982
983 bpf_printk("reqid %d spi 0x%x remote ip 0x%x\n",
984 x.reqid, bpf_ntohl(x.spi),
985 bpf_ntohl(x.remote_ipv4));
986 return TC_ACT_OK;
987 }
988
989 char _license[] SEC("license") = "GPL";
990