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