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 "vmlinux.h"
10 #include <bpf/bpf_core_read.h>
11 #include <bpf/bpf_helpers.h>
12 #include <bpf/bpf_endian.h>
13 #include "bpf_kfuncs.h"
14 #include "bpf_tracing_net.h"
15
16 #define log_err(__ret) bpf_printk("ERROR line:%d ret:%d\n", __LINE__, __ret)
17
18 #define VXLAN_UDP_PORT 4789
19 #define ETH_P_IP 0x0800
20 #define PACKET_HOST 0
21 #define TUNNEL_CSUM bpf_htons(0x01)
22 #define TUNNEL_KEY bpf_htons(0x04)
23
24 /* Only IPv4 address assigned to veth1.
25 * 172.16.1.200
26 */
27 #define ASSIGNED_ADDR_VETH1 0xac1001c8
28
29 int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
30 struct bpf_fou_encap *encap, int type) __ksym;
31 int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
32 struct bpf_fou_encap *encap) __ksym;
33 struct xfrm_state *
34 bpf_xdp_get_xfrm_state(struct xdp_md *ctx, struct bpf_xfrm_state_opts *opts,
35 u32 opts__sz) __ksym;
36 void bpf_xdp_xfrm_state_release(struct xfrm_state *x) __ksym;
37
38 struct {
39 __uint(type, BPF_MAP_TYPE_ARRAY);
40 __uint(max_entries, 1);
41 __type(key, __u32);
42 __type(value, __u32);
43 } local_ip_map SEC(".maps");
44
45 SEC("tc")
gre_set_tunnel(struct __sk_buff * skb)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 log_err(ret);
61 return TC_ACT_SHOT;
62 }
63
64 return TC_ACT_OK;
65 }
66
67 SEC("tc")
gre_set_tunnel_no_key(struct __sk_buff * skb)68 int gre_set_tunnel_no_key(struct __sk_buff *skb)
69 {
70 int ret;
71 struct bpf_tunnel_key key;
72
73 __builtin_memset(&key, 0x0, sizeof(key));
74 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
75 key.tunnel_ttl = 64;
76
77 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
78 BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER |
79 BPF_F_NO_TUNNEL_KEY);
80 if (ret < 0) {
81 log_err(ret);
82 return TC_ACT_SHOT;
83 }
84
85 return TC_ACT_OK;
86 }
87
88 SEC("tc")
gre_get_tunnel(struct __sk_buff * skb)89 int gre_get_tunnel(struct __sk_buff *skb)
90 {
91 int ret;
92 struct bpf_tunnel_key key;
93
94 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
95 if (ret < 0) {
96 log_err(ret);
97 return TC_ACT_SHOT;
98 }
99
100 bpf_printk("key %d remote ip 0x%x\n", key.tunnel_id, key.remote_ipv4);
101 return TC_ACT_OK;
102 }
103
104 SEC("tc")
ip6gretap_set_tunnel(struct __sk_buff * skb)105 int ip6gretap_set_tunnel(struct __sk_buff *skb)
106 {
107 struct bpf_tunnel_key key;
108 int ret;
109
110 __builtin_memset(&key, 0x0, sizeof(key));
111 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
112 key.tunnel_id = 2;
113 key.tunnel_tos = 0;
114 key.tunnel_ttl = 64;
115 key.tunnel_label = 0xabcde;
116
117 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
118 BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
119 BPF_F_SEQ_NUMBER);
120 if (ret < 0) {
121 log_err(ret);
122 return TC_ACT_SHOT;
123 }
124
125 return TC_ACT_OK;
126 }
127
128 SEC("tc")
ip6gretap_get_tunnel(struct __sk_buff * skb)129 int ip6gretap_get_tunnel(struct __sk_buff *skb)
130 {
131 struct bpf_tunnel_key key;
132 int ret;
133
134 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
135 BPF_F_TUNINFO_IPV6);
136 if (ret < 0) {
137 log_err(ret);
138 return TC_ACT_SHOT;
139 }
140
141 bpf_printk("key %d remote ip6 ::%x label %x\n",
142 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
143
144 return TC_ACT_OK;
145 }
146
147 SEC("tc")
erspan_set_tunnel(struct __sk_buff * skb)148 int erspan_set_tunnel(struct __sk_buff *skb)
149 {
150 struct bpf_tunnel_key key;
151 struct erspan_metadata md;
152 int ret;
153
154 __builtin_memset(&key, 0x0, sizeof(key));
155 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
156 key.tunnel_id = 2;
157 key.tunnel_tos = 0;
158 key.tunnel_ttl = 64;
159
160 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
161 BPF_F_ZERO_CSUM_TX);
162 if (ret < 0) {
163 log_err(ret);
164 return TC_ACT_SHOT;
165 }
166
167 __builtin_memset(&md, 0, sizeof(md));
168 #ifdef ERSPAN_V1
169 md.version = 1;
170 md.u.index = bpf_htonl(123);
171 #else
172 __u8 direction = 1;
173 __u8 hwid = 7;
174
175 md.version = 2;
176 BPF_CORE_WRITE_BITFIELD(&md.u.md2, dir, direction);
177 BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid, (hwid & 0xf));
178 BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid_upper, (hwid >> 4) & 0x3);
179 #endif
180
181 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
182 if (ret < 0) {
183 log_err(ret);
184 return TC_ACT_SHOT;
185 }
186
187 return TC_ACT_OK;
188 }
189
190 SEC("tc")
erspan_get_tunnel(struct __sk_buff * skb)191 int erspan_get_tunnel(struct __sk_buff *skb)
192 {
193 struct bpf_tunnel_key key;
194 struct erspan_metadata md;
195 int ret;
196
197 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
198 if (ret < 0) {
199 log_err(ret);
200 return TC_ACT_SHOT;
201 }
202
203 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
204 if (ret < 0) {
205 log_err(ret);
206 return TC_ACT_SHOT;
207 }
208
209 bpf_printk("key %d remote ip 0x%x erspan version %d\n",
210 key.tunnel_id, key.remote_ipv4, md.version);
211
212 #ifdef ERSPAN_V1
213 index = bpf_ntohl(md.u.index);
214 bpf_printk("\tindex %x\n", index);
215 #else
216 bpf_printk("\tdirection %d hwid %x timestamp %u\n",
217 BPF_CORE_READ_BITFIELD(&md.u.md2, dir),
218 (BPF_CORE_READ_BITFIELD(&md.u.md2, hwid_upper) << 4) +
219 BPF_CORE_READ_BITFIELD(&md.u.md2, hwid),
220 bpf_ntohl(md.u.md2.timestamp));
221 #endif
222
223 return TC_ACT_OK;
224 }
225
226 SEC("tc")
ip4ip6erspan_set_tunnel(struct __sk_buff * skb)227 int ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
228 {
229 struct bpf_tunnel_key key;
230 struct erspan_metadata md;
231 int ret;
232
233 __builtin_memset(&key, 0x0, sizeof(key));
234 key.remote_ipv6[3] = bpf_htonl(0x11);
235 key.tunnel_id = 2;
236 key.tunnel_tos = 0;
237 key.tunnel_ttl = 64;
238
239 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
240 BPF_F_TUNINFO_IPV6);
241 if (ret < 0) {
242 log_err(ret);
243 return TC_ACT_SHOT;
244 }
245
246 __builtin_memset(&md, 0, sizeof(md));
247
248 #ifdef ERSPAN_V1
249 md.u.index = bpf_htonl(123);
250 md.version = 1;
251 #else
252 __u8 direction = 0;
253 __u8 hwid = 17;
254
255 md.version = 2;
256 BPF_CORE_WRITE_BITFIELD(&md.u.md2, dir, direction);
257 BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid, (hwid & 0xf));
258 BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid_upper, (hwid >> 4) & 0x3);
259 #endif
260
261 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
262 if (ret < 0) {
263 log_err(ret);
264 return TC_ACT_SHOT;
265 }
266
267 return TC_ACT_OK;
268 }
269
270 SEC("tc")
ip4ip6erspan_get_tunnel(struct __sk_buff * skb)271 int ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
272 {
273 struct bpf_tunnel_key key;
274 struct erspan_metadata md;
275 int ret;
276
277 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
278 BPF_F_TUNINFO_IPV6);
279 if (ret < 0) {
280 log_err(ret);
281 return TC_ACT_SHOT;
282 }
283
284 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
285 if (ret < 0) {
286 log_err(ret);
287 return TC_ACT_SHOT;
288 }
289
290 bpf_printk("ip6erspan get key %d remote ip6 ::%x erspan version %d\n",
291 key.tunnel_id, key.remote_ipv4, md.version);
292
293 #ifdef ERSPAN_V1
294 index = bpf_ntohl(md.u.index);
295 bpf_printk("\tindex %x\n", index);
296 #else
297 bpf_printk("\tdirection %d hwid %x timestamp %u\n",
298 BPF_CORE_READ_BITFIELD(&md.u.md2, dir),
299 (BPF_CORE_READ_BITFIELD(&md.u.md2, hwid_upper) << 4) +
300 BPF_CORE_READ_BITFIELD(&md.u.md2, hwid),
301 bpf_ntohl(md.u.md2.timestamp));
302 #endif
303
304 return TC_ACT_OK;
305 }
306
307 SEC("tc")
vxlan_set_tunnel_dst(struct __sk_buff * skb)308 int vxlan_set_tunnel_dst(struct __sk_buff *skb)
309 {
310 struct bpf_tunnel_key key;
311 struct vxlan_metadata md;
312 __u32 index = 0;
313 __u32 *local_ip = NULL;
314 int ret = 0;
315
316 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
317 if (!local_ip) {
318 log_err(ret);
319 return TC_ACT_SHOT;
320 }
321
322 __builtin_memset(&key, 0x0, sizeof(key));
323 key.local_ipv4 = 0xac100164; /* 172.16.1.100 */
324 key.remote_ipv4 = *local_ip;
325 key.tunnel_id = 2;
326 key.tunnel_tos = 0;
327 key.tunnel_ttl = 64;
328
329 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
330 BPF_F_ZERO_CSUM_TX);
331 if (ret < 0) {
332 log_err(ret);
333 return TC_ACT_SHOT;
334 }
335
336 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
337 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
338 if (ret < 0) {
339 log_err(ret);
340 return TC_ACT_SHOT;
341 }
342
343 return TC_ACT_OK;
344 }
345
346 SEC("tc")
vxlan_set_tunnel_src(struct __sk_buff * skb)347 int vxlan_set_tunnel_src(struct __sk_buff *skb)
348 {
349 struct bpf_tunnel_key key;
350 struct vxlan_metadata md;
351 __u32 index = 0;
352 __u32 *local_ip = NULL;
353 int ret = 0;
354
355 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
356 if (!local_ip) {
357 log_err(ret);
358 return TC_ACT_SHOT;
359 }
360
361 __builtin_memset(&key, 0x0, sizeof(key));
362 key.local_ipv4 = *local_ip;
363 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
364 key.tunnel_id = 2;
365 key.tunnel_tos = 0;
366 key.tunnel_ttl = 64;
367
368 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
369 BPF_F_ZERO_CSUM_TX);
370 if (ret < 0) {
371 log_err(ret);
372 return TC_ACT_SHOT;
373 }
374
375 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
376 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
377 if (ret < 0) {
378 log_err(ret);
379 return TC_ACT_SHOT;
380 }
381
382 return TC_ACT_OK;
383 }
384
385 SEC("tc")
vxlan_get_tunnel_src(struct __sk_buff * skb)386 int vxlan_get_tunnel_src(struct __sk_buff *skb)
387 {
388 int ret;
389 struct bpf_tunnel_key key;
390 struct vxlan_metadata md;
391
392 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
393 BPF_F_TUNINFO_FLAGS);
394 if (ret < 0) {
395 log_err(ret);
396 return TC_ACT_SHOT;
397 }
398
399 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
400 if (ret < 0) {
401 log_err(ret);
402 return TC_ACT_SHOT;
403 }
404
405 if (key.local_ipv4 != ASSIGNED_ADDR_VETH1 || md.gbp != 0x800FF ||
406 !(key.tunnel_flags & TUNNEL_KEY) ||
407 (key.tunnel_flags & TUNNEL_CSUM)) {
408 bpf_printk("vxlan key %d local ip 0x%x remote ip 0x%x gbp 0x%x flags 0x%x\n",
409 key.tunnel_id, key.local_ipv4,
410 key.remote_ipv4, md.gbp,
411 bpf_ntohs(key.tunnel_flags));
412 log_err(ret);
413 return TC_ACT_SHOT;
414 }
415
416 return TC_ACT_OK;
417 }
418
419 SEC("tc")
veth_set_outer_dst(struct __sk_buff * skb)420 int veth_set_outer_dst(struct __sk_buff *skb)
421 {
422 struct ethhdr *eth = (struct ethhdr *)(long)skb->data;
423 __u32 assigned_ip = bpf_htonl(ASSIGNED_ADDR_VETH1);
424 void *data_end = (void *)(long)skb->data_end;
425 struct udphdr *udph;
426 struct iphdr *iph;
427 int ret = 0;
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 __u32 index = 0;
477 __u32 *local_ip;
478 int ret = 0;
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 __u32 index = 0;
508 __u32 *local_ip;
509 int ret = 0;
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 __u32 index = 0;
539 __u32 *local_ip;
540 int ret = 0;
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")
ipip_gue_set_tunnel(struct __sk_buff * skb)738 int ipip_gue_set_tunnel(struct __sk_buff *skb)
739 {
740 struct bpf_tunnel_key key = {};
741 struct bpf_fou_encap encap = {};
742 void *data = (void *)(long)skb->data;
743 struct iphdr *iph = data;
744 void *data_end = (void *)(long)skb->data_end;
745 int ret;
746
747 if (data + sizeof(*iph) > data_end) {
748 log_err(1);
749 return TC_ACT_SHOT;
750 }
751
752 key.tunnel_ttl = 64;
753 if (iph->protocol == IPPROTO_ICMP)
754 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
755
756 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
757 if (ret < 0) {
758 log_err(ret);
759 return TC_ACT_SHOT;
760 }
761
762 encap.sport = 0;
763 encap.dport = bpf_htons(5555);
764
765 ret = bpf_skb_set_fou_encap(skb, &encap, FOU_BPF_ENCAP_GUE);
766 if (ret < 0) {
767 log_err(ret);
768 return TC_ACT_SHOT;
769 }
770
771 return TC_ACT_OK;
772 }
773
774 SEC("tc")
ipip_fou_set_tunnel(struct __sk_buff * skb)775 int ipip_fou_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_FOU);
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_encap_get_tunnel(struct __sk_buff * skb)812 int ipip_encap_get_tunnel(struct __sk_buff *skb)
813 {
814 int ret;
815 struct bpf_tunnel_key key = {};
816 struct bpf_fou_encap encap = {};
817
818 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
819 if (ret < 0) {
820 log_err(ret);
821 return TC_ACT_SHOT;
822 }
823
824 ret = bpf_skb_get_fou_encap(skb, &encap);
825 if (ret < 0) {
826 log_err(ret);
827 return TC_ACT_SHOT;
828 }
829
830 if (bpf_ntohs(encap.dport) != 5555)
831 return TC_ACT_SHOT;
832
833 bpf_printk("%d remote ip 0x%x, sport %d, dport %d\n", ret,
834 key.remote_ipv4, bpf_ntohs(encap.sport),
835 bpf_ntohs(encap.dport));
836 return TC_ACT_OK;
837 }
838
839 SEC("tc")
ipip6_set_tunnel(struct __sk_buff * skb)840 int ipip6_set_tunnel(struct __sk_buff *skb)
841 {
842 struct bpf_tunnel_key key = {};
843 void *data = (void *)(long)skb->data;
844 struct iphdr *iph = data;
845 void *data_end = (void *)(long)skb->data_end;
846 int ret;
847
848 /* single length check */
849 if (data + sizeof(*iph) > data_end) {
850 log_err(1);
851 return TC_ACT_SHOT;
852 }
853
854 __builtin_memset(&key, 0x0, sizeof(key));
855 key.tunnel_ttl = 64;
856 if (iph->protocol == IPPROTO_ICMP) {
857 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
858 }
859
860 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
861 BPF_F_TUNINFO_IPV6);
862 if (ret < 0) {
863 log_err(ret);
864 return TC_ACT_SHOT;
865 }
866
867 return TC_ACT_OK;
868 }
869
870 SEC("tc")
ipip6_get_tunnel(struct __sk_buff * skb)871 int ipip6_get_tunnel(struct __sk_buff *skb)
872 {
873 int ret;
874 struct bpf_tunnel_key key;
875
876 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
877 BPF_F_TUNINFO_IPV6);
878 if (ret < 0) {
879 log_err(ret);
880 return TC_ACT_SHOT;
881 }
882
883 bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
884 bpf_htonl(key.remote_ipv6[3]));
885 return TC_ACT_OK;
886 }
887
888 SEC("tc")
ip6ip6_set_tunnel(struct __sk_buff * skb)889 int ip6ip6_set_tunnel(struct __sk_buff *skb)
890 {
891 struct bpf_tunnel_key key = {};
892 void *data = (void *)(long)skb->data;
893 struct ipv6hdr *iph = data;
894 void *data_end = (void *)(long)skb->data_end;
895 int ret;
896
897 /* single length check */
898 if (data + sizeof(*iph) > data_end) {
899 log_err(1);
900 return TC_ACT_SHOT;
901 }
902
903 key.tunnel_ttl = 64;
904 if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
905 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
906 }
907
908 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
909 BPF_F_TUNINFO_IPV6);
910 if (ret < 0) {
911 log_err(ret);
912 return TC_ACT_SHOT;
913 }
914
915 return TC_ACT_OK;
916 }
917
918 SEC("tc")
ip6ip6_get_tunnel(struct __sk_buff * skb)919 int ip6ip6_get_tunnel(struct __sk_buff *skb)
920 {
921 int ret;
922 struct bpf_tunnel_key key;
923
924 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
925 BPF_F_TUNINFO_IPV6);
926 if (ret < 0) {
927 log_err(ret);
928 return TC_ACT_SHOT;
929 }
930
931 bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
932 bpf_htonl(key.remote_ipv6[3]));
933 return TC_ACT_OK;
934 }
935
936 volatile int xfrm_reqid = 0;
937 volatile int xfrm_spi = 0;
938 volatile int xfrm_remote_ip = 0;
939
940 SEC("tc")
xfrm_get_state(struct __sk_buff * skb)941 int xfrm_get_state(struct __sk_buff *skb)
942 {
943 struct bpf_xfrm_state x;
944 int ret;
945
946 ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
947 if (ret < 0)
948 return TC_ACT_OK;
949
950 xfrm_reqid = x.reqid;
951 xfrm_spi = bpf_ntohl(x.spi);
952 xfrm_remote_ip = bpf_ntohl(x.remote_ipv4);
953
954 return TC_ACT_OK;
955 }
956
957 volatile int xfrm_replay_window = 0;
958
959 SEC("xdp")
xfrm_get_state_xdp(struct xdp_md * xdp)960 int xfrm_get_state_xdp(struct xdp_md *xdp)
961 {
962 struct bpf_xfrm_state_opts opts = {};
963 struct xfrm_state *x = NULL;
964 struct ip_esp_hdr *esph;
965 struct bpf_dynptr ptr;
966 u8 esph_buf[8] = {};
967 u8 iph_buf[20] = {};
968 struct iphdr *iph;
969 u32 off;
970
971 if (bpf_dynptr_from_xdp(xdp, 0, &ptr))
972 goto out;
973
974 off = sizeof(struct ethhdr);
975 iph = bpf_dynptr_slice(&ptr, off, iph_buf, sizeof(iph_buf));
976 if (!iph || iph->protocol != IPPROTO_ESP)
977 goto out;
978
979 off += sizeof(struct iphdr);
980 esph = bpf_dynptr_slice(&ptr, off, esph_buf, sizeof(esph_buf));
981 if (!esph)
982 goto out;
983
984 opts.netns_id = BPF_F_CURRENT_NETNS;
985 opts.daddr.a4 = iph->daddr;
986 opts.spi = esph->spi;
987 opts.proto = IPPROTO_ESP;
988 opts.family = AF_INET;
989
990 x = bpf_xdp_get_xfrm_state(xdp, &opts, sizeof(opts));
991 if (!x)
992 goto out;
993
994 if (!x->replay_esn)
995 goto out;
996
997 xfrm_replay_window = x->replay_esn->replay_window;
998 out:
999 if (x)
1000 bpf_xdp_xfrm_state_release(x);
1001 return XDP_PASS;
1002 }
1003
1004 char _license[] SEC("license") = "GPL";
1005