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