root/samples/bpf/xdp_redirect_kern.c

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

DEFINITIONS

This source file includes following definitions.
  1. swap_src_dst_mac
  2. SEC
  3. SEC

   1 /* Copyright (c) 2016 John Fastabend <john.r.fastabend@intel.com>
   2  *
   3  * This program is free software; you can redistribute it and/or
   4  * modify it under the terms of version 2 of the GNU General Public
   5  * License as published by the Free Software Foundation.
   6  *
   7  * This program is distributed in the hope that it will be useful, but
   8  * WITHOUT ANY WARRANTY; without even the implied warranty of
   9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10  * General Public License for more details.
  11  */
  12 #define KBUILD_MODNAME "foo"
  13 #include <uapi/linux/bpf.h>
  14 #include <linux/in.h>
  15 #include <linux/if_ether.h>
  16 #include <linux/if_packet.h>
  17 #include <linux/if_vlan.h>
  18 #include <linux/ip.h>
  19 #include <linux/ipv6.h>
  20 #include "bpf_helpers.h"
  21 
  22 struct {
  23         __uint(type, BPF_MAP_TYPE_ARRAY);
  24         __type(key, int);
  25         __type(value, int);
  26         __uint(max_entries, 1);
  27 } tx_port SEC(".maps");
  28 
  29 /* Count RX packets, as XDP bpf_prog doesn't get direct TX-success
  30  * feedback.  Redirect TX errors can be caught via a tracepoint.
  31  */
  32 struct {
  33         __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
  34         __type(key, u32);
  35         __type(value, long);
  36         __uint(max_entries, 1);
  37 } rxcnt SEC(".maps");
  38 
  39 static void swap_src_dst_mac(void *data)
  40 {
  41         unsigned short *p = data;
  42         unsigned short dst[3];
  43 
  44         dst[0] = p[0];
  45         dst[1] = p[1];
  46         dst[2] = p[2];
  47         p[0] = p[3];
  48         p[1] = p[4];
  49         p[2] = p[5];
  50         p[3] = dst[0];
  51         p[4] = dst[1];
  52         p[5] = dst[2];
  53 }
  54 
  55 SEC("xdp_redirect")
  56 int xdp_redirect_prog(struct xdp_md *ctx)
  57 {
  58         void *data_end = (void *)(long)ctx->data_end;
  59         void *data = (void *)(long)ctx->data;
  60         struct ethhdr *eth = data;
  61         int rc = XDP_DROP;
  62         int *ifindex, port = 0;
  63         long *value;
  64         u32 key = 0;
  65         u64 nh_off;
  66 
  67         nh_off = sizeof(*eth);
  68         if (data + nh_off > data_end)
  69                 return rc;
  70 
  71         ifindex = bpf_map_lookup_elem(&tx_port, &port);
  72         if (!ifindex)
  73                 return rc;
  74 
  75         value = bpf_map_lookup_elem(&rxcnt, &key);
  76         if (value)
  77                 *value += 1;
  78 
  79         swap_src_dst_mac(data);
  80         return bpf_redirect(*ifindex, 0);
  81 }
  82 
  83 /* Redirect require an XDP bpf_prog loaded on the TX device */
  84 SEC("xdp_redirect_dummy")
  85 int xdp_redirect_dummy_prog(struct xdp_md *ctx)
  86 {
  87         return XDP_PASS;
  88 }
  89 
  90 char _license[] SEC("license") = "GPL";

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