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