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, ret2;
 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                ERROR(ret);
 451                return TC_ACT_SHOT;
 452        }
 453
 454        bpf_trace_printk(fmt, sizeof(fmt),
 455                        key.tunnel_id, key.remote_ipv4, gopt.opt_class);
 456        return TC_ACT_OK;
 457}
 458
 459SEC("ip6geneve_set_tunnel")
 460int _ip6geneve_set_tunnel(struct __sk_buff *skb)
 461{
 462        struct bpf_tunnel_key key;
 463        struct geneve_opt gopt;
 464        int ret;
 465
 466        __builtin_memset(&key, 0x0, sizeof(key));
 467        key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
 468        key.tunnel_id = 22;
 469        key.tunnel_tos = 0;
 470        key.tunnel_ttl = 64;
 471
 472        ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 473                                     BPF_F_TUNINFO_IPV6);
 474        if (ret < 0) {
 475                ERROR(ret);
 476                return TC_ACT_SHOT;
 477        }
 478
 479        __builtin_memset(&gopt, 0x0, sizeof(gopt));
 480        gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
 481        gopt.type = 0x08;
 482        gopt.r1 = 0;
 483        gopt.r2 = 0;
 484        gopt.r3 = 0;
 485        gopt.length = 2; /* 4-byte multiple */
 486        *(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef);
 487
 488        ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
 489        if (ret < 0) {
 490                ERROR(ret);
 491                return TC_ACT_SHOT;
 492        }
 493
 494        return TC_ACT_OK;
 495}
 496
 497SEC("ip6geneve_get_tunnel")
 498int _ip6geneve_get_tunnel(struct __sk_buff *skb)
 499{
 500        char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
 501        struct bpf_tunnel_key key;
 502        struct geneve_opt gopt;
 503        int ret;
 504
 505        ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
 506                                     BPF_F_TUNINFO_IPV6);
 507        if (ret < 0) {
 508                ERROR(ret);
 509                return TC_ACT_SHOT;
 510        }
 511
 512        ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
 513        if (ret < 0) {
 514                ERROR(ret);
 515                return TC_ACT_SHOT;
 516        }
 517
 518        bpf_trace_printk(fmt, sizeof(fmt),
 519                        key.tunnel_id, key.remote_ipv4, gopt.opt_class);
 520
 521        return TC_ACT_OK;
 522}
 523
 524SEC("ipip_set_tunnel")
 525int _ipip_set_tunnel(struct __sk_buff *skb)
 526{
 527        struct bpf_tunnel_key key = {};
 528        void *data = (void *)(long)skb->data;
 529        struct iphdr *iph = data;
 530        void *data_end = (void *)(long)skb->data_end;
 531        int ret;
 532
 533        /* single length check */
 534        if (data + sizeof(*iph) > data_end) {
 535                ERROR(1);
 536                return TC_ACT_SHOT;
 537        }
 538
 539        key.tunnel_ttl = 64;
 540        if (iph->protocol == IPPROTO_ICMP) {
 541                key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
 542        }
 543
 544        ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
 545        if (ret < 0) {
 546                ERROR(ret);
 547                return TC_ACT_SHOT;
 548        }
 549
 550        return TC_ACT_OK;
 551}
 552
 553SEC("ipip_get_tunnel")
 554int _ipip_get_tunnel(struct __sk_buff *skb)
 555{
 556        int ret;
 557        struct bpf_tunnel_key key;
 558        char fmt[] = "remote ip 0x%x\n";
 559
 560        ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
 561        if (ret < 0) {
 562                ERROR(ret);
 563                return TC_ACT_SHOT;
 564        }
 565
 566        bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
 567        return TC_ACT_OK;
 568}
 569
 570SEC("ipip6_set_tunnel")
 571int _ipip6_set_tunnel(struct __sk_buff *skb)
 572{
 573        struct bpf_tunnel_key key = {};
 574        void *data = (void *)(long)skb->data;
 575        struct iphdr *iph = data;
 576        void *data_end = (void *)(long)skb->data_end;
 577        int ret;
 578
 579        /* single length check */
 580        if (data + sizeof(*iph) > data_end) {
 581                ERROR(1);
 582                return TC_ACT_SHOT;
 583        }
 584
 585        __builtin_memset(&key, 0x0, sizeof(key));
 586        key.tunnel_ttl = 64;
 587        if (iph->protocol == IPPROTO_ICMP) {
 588                key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
 589        }
 590
 591        ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 592                                     BPF_F_TUNINFO_IPV6);
 593        if (ret < 0) {
 594                ERROR(ret);
 595                return TC_ACT_SHOT;
 596        }
 597
 598        return TC_ACT_OK;
 599}
 600
 601SEC("ipip6_get_tunnel")
 602int _ipip6_get_tunnel(struct __sk_buff *skb)
 603{
 604        int ret;
 605        struct bpf_tunnel_key key;
 606        char fmt[] = "remote ip6 %x::%x\n";
 607
 608        ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
 609                                     BPF_F_TUNINFO_IPV6);
 610        if (ret < 0) {
 611                ERROR(ret);
 612                return TC_ACT_SHOT;
 613        }
 614
 615        bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
 616                         bpf_htonl(key.remote_ipv6[3]));
 617        return TC_ACT_OK;
 618}
 619
 620SEC("ip6ip6_set_tunnel")
 621int _ip6ip6_set_tunnel(struct __sk_buff *skb)
 622{
 623        struct bpf_tunnel_key key = {};
 624        void *data = (void *)(long)skb->data;
 625        struct ipv6hdr *iph = data;
 626        void *data_end = (void *)(long)skb->data_end;
 627        int ret;
 628
 629        /* single length check */
 630        if (data + sizeof(*iph) > data_end) {
 631                ERROR(1);
 632                return TC_ACT_SHOT;
 633        }
 634
 635        key.tunnel_ttl = 64;
 636        if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
 637                key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
 638        }
 639
 640        ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 641                                     BPF_F_TUNINFO_IPV6);
 642        if (ret < 0) {
 643                ERROR(ret);
 644                return TC_ACT_SHOT;
 645        }
 646
 647        return TC_ACT_OK;
 648}
 649
 650SEC("ip6ip6_get_tunnel")
 651int _ip6ip6_get_tunnel(struct __sk_buff *skb)
 652{
 653        int ret;
 654        struct bpf_tunnel_key key;
 655        char fmt[] = "remote ip6 %x::%x\n";
 656
 657        ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
 658                                     BPF_F_TUNINFO_IPV6);
 659        if (ret < 0) {
 660                ERROR(ret);
 661                return TC_ACT_SHOT;
 662        }
 663
 664        bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
 665                         bpf_htonl(key.remote_ipv6[3]));
 666        return TC_ACT_OK;
 667}
 668
 669SEC("xfrm_get_state")
 670int _xfrm_get_state(struct __sk_buff *skb)
 671{
 672        struct bpf_xfrm_state x;
 673        char fmt[] = "reqid %d spi 0x%x remote ip 0x%x\n";
 674        int ret;
 675
 676        ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
 677        if (ret < 0)
 678                return TC_ACT_OK;
 679
 680        bpf_trace_printk(fmt, sizeof(fmt), x.reqid, bpf_ntohl(x.spi),
 681                         bpf_ntohl(x.remote_ipv4));
 682        return TC_ACT_OK;
 683}
 684
 685char _license[] SEC("license") = "GPL";
 686