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