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

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

DEFINITIONS

This source file includes following definitions.
  1. SEC

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright (c) 2018 Facebook
   3 
   4 #include <string.h>
   5 
   6 #include <linux/stddef.h>
   7 #include <linux/bpf.h>
   8 #include <linux/in.h>
   9 #include <linux/in6.h>
  10 #include <sys/socket.h>
  11 
  12 #include "bpf_helpers.h"
  13 #include "bpf_endian.h"
  14 
  15 #define SRC_REWRITE_IP6_0       0
  16 #define SRC_REWRITE_IP6_1       0
  17 #define SRC_REWRITE_IP6_2       0
  18 #define SRC_REWRITE_IP6_3       6
  19 
  20 #define DST_REWRITE_IP6_0       0
  21 #define DST_REWRITE_IP6_1       0
  22 #define DST_REWRITE_IP6_2       0
  23 #define DST_REWRITE_IP6_3       1
  24 
  25 #define DST_REWRITE_PORT6       6666
  26 
  27 int _version SEC("version") = 1;
  28 
  29 SEC("cgroup/connect6")
  30 int connect_v6_prog(struct bpf_sock_addr *ctx)
  31 {
  32         struct bpf_sock_tuple tuple = {};
  33         struct sockaddr_in6 sa;
  34         struct bpf_sock *sk;
  35 
  36         /* Verify that new destination is available. */
  37         memset(&tuple.ipv6.saddr, 0, sizeof(tuple.ipv6.saddr));
  38         memset(&tuple.ipv6.sport, 0, sizeof(tuple.ipv6.sport));
  39 
  40         tuple.ipv6.daddr[0] = bpf_htonl(DST_REWRITE_IP6_0);
  41         tuple.ipv6.daddr[1] = bpf_htonl(DST_REWRITE_IP6_1);
  42         tuple.ipv6.daddr[2] = bpf_htonl(DST_REWRITE_IP6_2);
  43         tuple.ipv6.daddr[3] = bpf_htonl(DST_REWRITE_IP6_3);
  44 
  45         tuple.ipv6.dport = bpf_htons(DST_REWRITE_PORT6);
  46 
  47         if (ctx->type != SOCK_STREAM && ctx->type != SOCK_DGRAM)
  48                 return 0;
  49         else if (ctx->type == SOCK_STREAM)
  50                 sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof(tuple.ipv6),
  51                                        BPF_F_CURRENT_NETNS, 0);
  52         else
  53                 sk = bpf_sk_lookup_udp(ctx, &tuple, sizeof(tuple.ipv6),
  54                                        BPF_F_CURRENT_NETNS, 0);
  55 
  56         if (!sk)
  57                 return 0;
  58 
  59         if (sk->src_ip6[0] != tuple.ipv6.daddr[0] ||
  60             sk->src_ip6[1] != tuple.ipv6.daddr[1] ||
  61             sk->src_ip6[2] != tuple.ipv6.daddr[2] ||
  62             sk->src_ip6[3] != tuple.ipv6.daddr[3] ||
  63             sk->src_port != DST_REWRITE_PORT6) {
  64                 bpf_sk_release(sk);
  65                 return 0;
  66         }
  67 
  68         bpf_sk_release(sk);
  69 
  70         /* Rewrite destination. */
  71         ctx->user_ip6[0] = bpf_htonl(DST_REWRITE_IP6_0);
  72         ctx->user_ip6[1] = bpf_htonl(DST_REWRITE_IP6_1);
  73         ctx->user_ip6[2] = bpf_htonl(DST_REWRITE_IP6_2);
  74         ctx->user_ip6[3] = bpf_htonl(DST_REWRITE_IP6_3);
  75 
  76         ctx->user_port = bpf_htons(DST_REWRITE_PORT6);
  77 
  78         /* Rewrite source. */
  79         memset(&sa, 0, sizeof(sa));
  80 
  81         sa.sin6_family = AF_INET6;
  82         sa.sin6_port = bpf_htons(0);
  83 
  84         sa.sin6_addr.s6_addr32[0] = bpf_htonl(SRC_REWRITE_IP6_0);
  85         sa.sin6_addr.s6_addr32[1] = bpf_htonl(SRC_REWRITE_IP6_1);
  86         sa.sin6_addr.s6_addr32[2] = bpf_htonl(SRC_REWRITE_IP6_2);
  87         sa.sin6_addr.s6_addr32[3] = bpf_htonl(SRC_REWRITE_IP6_3);
  88 
  89         if (bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa)) != 0)
  90                 return 0;
  91 
  92         return 1;
  93 }
  94 
  95 char _license[] SEC("license") = "GPL";

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