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