root/tools/testing/selftests/bpf/progs/test_tunnel_kern.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SEC
  2. SEC
  3. SEC
  4. SEC
  5. SEC
  6. SEC
  7. SEC
  8. SEC
  9. SEC
  10. SEC
  11. SEC
  12. SEC
  13. SEC
  14. SEC
  15. SEC
  16. SEC
  17. SEC
  18. SEC
  19. SEC
  20. SEC
  21. SEC
  22. SEC
  23. SEC

   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";

/* [<][>][^][v][top][bottom][index][help] */