linux/samples/bpf/xdp_redirect_map.bpf.c
<<
>>
Prefs
   1/* Copyright (c) 2017 Covalent IO, Inc. http://covalent.io
   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
  14#include "vmlinux.h"
  15#include "xdp_sample.bpf.h"
  16#include "xdp_sample_shared.h"
  17
  18/* The 2nd xdp prog on egress does not support skb mode, so we define two
  19 * maps, tx_port_general and tx_port_native.
  20 */
  21struct {
  22        __uint(type, BPF_MAP_TYPE_DEVMAP);
  23        __uint(key_size, sizeof(int));
  24        __uint(value_size, sizeof(int));
  25        __uint(max_entries, 1);
  26} tx_port_general SEC(".maps");
  27
  28struct {
  29        __uint(type, BPF_MAP_TYPE_DEVMAP);
  30        __uint(key_size, sizeof(int));
  31        __uint(value_size, sizeof(struct bpf_devmap_val));
  32        __uint(max_entries, 1);
  33} tx_port_native SEC(".maps");
  34
  35/* store egress interface mac address */
  36const volatile char tx_mac_addr[ETH_ALEN];
  37
  38static __always_inline int xdp_redirect_map(struct xdp_md *ctx, void *redirect_map)
  39{
  40        void *data_end = (void *)(long)ctx->data_end;
  41        void *data = (void *)(long)ctx->data;
  42        u32 key = bpf_get_smp_processor_id();
  43        struct ethhdr *eth = data;
  44        struct datarec *rec;
  45        u64 nh_off;
  46
  47        nh_off = sizeof(*eth);
  48        if (data + nh_off > data_end)
  49                return XDP_DROP;
  50
  51        rec = bpf_map_lookup_elem(&rx_cnt, &key);
  52        if (!rec)
  53                return XDP_PASS;
  54        NO_TEAR_INC(rec->processed);
  55        swap_src_dst_mac(data);
  56        return bpf_redirect_map(redirect_map, 0, 0);
  57}
  58
  59SEC("xdp")
  60int xdp_redirect_map_general(struct xdp_md *ctx)
  61{
  62        return xdp_redirect_map(ctx, &tx_port_general);
  63}
  64
  65SEC("xdp")
  66int xdp_redirect_map_native(struct xdp_md *ctx)
  67{
  68        return xdp_redirect_map(ctx, &tx_port_native);
  69}
  70
  71SEC("xdp_devmap/egress")
  72int xdp_redirect_map_egress(struct xdp_md *ctx)
  73{
  74        void *data_end = (void *)(long)ctx->data_end;
  75        void *data = (void *)(long)ctx->data;
  76        struct ethhdr *eth = data;
  77        u64 nh_off;
  78
  79        nh_off = sizeof(*eth);
  80        if (data + nh_off > data_end)
  81                return XDP_DROP;
  82
  83        __builtin_memcpy(eth->h_source, (const char *)tx_mac_addr, ETH_ALEN);
  84
  85        return XDP_PASS;
  86}
  87
  88/* Redirect require an XDP bpf_prog loaded on the TX device */
  89SEC("xdp")
  90int xdp_redirect_dummy_prog(struct xdp_md *ctx)
  91{
  92        return XDP_PASS;
  93}
  94
  95char _license[] SEC("license") = "GPL";
  96