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