root/tools/testing/selftests/bpf/progs/connect4_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_IP4         0x7f000004U
  16 #define DST_REWRITE_IP4         0x7f000001U
  17 #define DST_REWRITE_PORT4       4444
  18 
  19 int _version SEC("version") = 1;
  20 
  21 SEC("cgroup/connect4")
  22 int connect_v4_prog(struct bpf_sock_addr *ctx)
  23 {
  24         struct bpf_sock_tuple tuple = {};
  25         struct sockaddr_in sa;
  26         struct bpf_sock *sk;
  27 
  28         /* Verify that new destination is available. */
  29         memset(&tuple.ipv4.saddr, 0, sizeof(tuple.ipv4.saddr));
  30         memset(&tuple.ipv4.sport, 0, sizeof(tuple.ipv4.sport));
  31 
  32         tuple.ipv4.daddr = bpf_htonl(DST_REWRITE_IP4);
  33         tuple.ipv4.dport = bpf_htons(DST_REWRITE_PORT4);
  34 
  35         if (ctx->type != SOCK_STREAM && ctx->type != SOCK_DGRAM)
  36                 return 0;
  37         else if (ctx->type == SOCK_STREAM)
  38                 sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof(tuple.ipv4),
  39                                        BPF_F_CURRENT_NETNS, 0);
  40         else
  41                 sk = bpf_sk_lookup_udp(ctx, &tuple, sizeof(tuple.ipv4),
  42                                        BPF_F_CURRENT_NETNS, 0);
  43 
  44         if (!sk)
  45                 return 0;
  46 
  47         if (sk->src_ip4 != tuple.ipv4.daddr ||
  48             sk->src_port != DST_REWRITE_PORT4) {
  49                 bpf_sk_release(sk);
  50                 return 0;
  51         }
  52 
  53         bpf_sk_release(sk);
  54 
  55         /* Rewrite destination. */
  56         ctx->user_ip4 = bpf_htonl(DST_REWRITE_IP4);
  57         ctx->user_port = bpf_htons(DST_REWRITE_PORT4);
  58 
  59         /* Rewrite source. */
  60         memset(&sa, 0, sizeof(sa));
  61 
  62         sa.sin_family = AF_INET;
  63         sa.sin_port = bpf_htons(0);
  64         sa.sin_addr.s_addr = bpf_htonl(SRC_REWRITE_IP4);
  65 
  66         if (bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa)) != 0)
  67                 return 0;
  68 
  69         return 1;
  70 }
  71 
  72 char _license[] SEC("license") = "GPL";

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