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