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