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