Loading...
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
29struct bpf_fou_encap___local {
30 __be16 sport;
31 __be16 dport;
32} __attribute__((preserve_access_index));
33
34enum bpf_fou_encap_type___local {
35 FOU_BPF_ENCAP_FOU___local,
36 FOU_BPF_ENCAP_GUE___local,
37};
38
39struct bpf_fou_encap;
40
41int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
42 struct bpf_fou_encap *encap, int type) __ksym;
43int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
44 struct bpf_fou_encap *encap) __ksym;
45struct xfrm_state *
46bpf_xdp_get_xfrm_state(struct xdp_md *ctx, struct bpf_xfrm_state_opts *opts,
47 u32 opts__sz) __ksym;
48void bpf_xdp_xfrm_state_release(struct xfrm_state *x) __ksym;
49
50struct {
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
57SEC("tc")
58int 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
79SEC("tc")
80int 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
100SEC("tc")
101int 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
116SEC("tc")
117int 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
140SEC("tc")
141int 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
159SEC("tc")
160int 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
202SEC("tc")
203int 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
238SEC("tc")
239int 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
282SEC("tc")
283int 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
319SEC("tc")
320int 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
358SEC("tc")
359int 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
397SEC("tc")
398int 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
431SEC("tc")
432int 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
484SEC("tc")
485int 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
515SEC("tc")
516int 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
546SEC("tc")
547int 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
582struct local_geneve_opt {
583 struct geneve_opt gopt;
584 int data;
585};
586
587SEC("tc")
588int 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
626SEC("tc")
627int 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
648SEC("tc")
649int 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
687SEC("tc")
688int 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
711SEC("tc")
712int 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
740SEC("tc")
741int 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
756SEC("tc")
757int 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
795SEC("tc")
796int 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
833SEC("tc")
834int 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
861SEC("tc")
862int 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
892SEC("tc")
893int 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
910SEC("tc")
911int 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
940SEC("tc")
941int 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
958volatile int xfrm_reqid = 0;
959volatile int xfrm_spi = 0;
960volatile int xfrm_remote_ip = 0;
961
962SEC("tc")
963int 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
979volatile int xfrm_replay_window = 0;
980
981SEC("xdp")
982int 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;
1020out:
1021 if (x)
1022 bpf_xdp_xfrm_state_release(x);
1023 return XDP_PASS;
1024}
1025
1026char _license[] SEC("license") = "GPL";
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
29int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
30 struct bpf_fou_encap *encap, int type) __ksym;
31int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
32 struct bpf_fou_encap *encap) __ksym;
33struct xfrm_state *
34bpf_xdp_get_xfrm_state(struct xdp_md *ctx, struct bpf_xfrm_state_opts *opts,
35 u32 opts__sz) __ksym;
36void bpf_xdp_xfrm_state_release(struct xfrm_state *x) __ksym;
37
38struct {
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
45SEC("tc")
46int 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
67SEC("tc")
68int 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
88SEC("tc")
89int 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
104SEC("tc")
105int 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
128SEC("tc")
129int 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
147SEC("tc")
148int 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
190SEC("tc")
191int 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
226SEC("tc")
227int 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
270SEC("tc")
271int 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
307SEC("tc")
308int 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
346SEC("tc")
347int 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
385SEC("tc")
386int 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
419SEC("tc")
420int 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
472SEC("tc")
473int 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
503SEC("tc")
504int 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
534SEC("tc")
535int 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
570SEC("tc")
571int 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
608SEC("tc")
609int 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
630SEC("tc")
631int 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
668SEC("tc")
669int 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
692SEC("tc")
693int 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
721SEC("tc")
722int 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
737SEC("tc")
738int 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
774SEC("tc")
775int 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
811SEC("tc")
812int 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
839SEC("tc")
840int 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
870SEC("tc")
871int 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
888SEC("tc")
889int 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
918SEC("tc")
919int 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
936volatile int xfrm_reqid = 0;
937volatile int xfrm_spi = 0;
938volatile int xfrm_remote_ip = 0;
939
940SEC("tc")
941int 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
957volatile int xfrm_replay_window = 0;
958
959SEC("xdp")
960int 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;
998out:
999 if (x)
1000 bpf_xdp_xfrm_state_release(x);
1001 return XDP_PASS;
1002}
1003
1004char _license[] SEC("license") = "GPL";