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