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