linux/samples/bpf/xdp_redirect_map_multi_kern.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#define KBUILD_MODNAME "foo"
   3#include <uapi/linux/bpf.h>
   4#include <linux/in.h>
   5#include <linux/if_ether.h>
   6#include <linux/ip.h>
   7#include <linux/ipv6.h>
   8#include <bpf/bpf_helpers.h>
   9
  10struct {
  11        __uint(type, BPF_MAP_TYPE_DEVMAP_HASH);
  12        __uint(key_size, sizeof(int));
  13        __uint(value_size, sizeof(int));
  14        __uint(max_entries, 32);
  15} forward_map_general SEC(".maps");
  16
  17struct {
  18        __uint(type, BPF_MAP_TYPE_DEVMAP_HASH);
  19        __uint(key_size, sizeof(int));
  20        __uint(value_size, sizeof(struct bpf_devmap_val));
  21        __uint(max_entries, 32);
  22} forward_map_native SEC(".maps");
  23
  24struct {
  25        __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
  26        __type(key, u32);
  27        __type(value, long);
  28        __uint(max_entries, 1);
  29} rxcnt SEC(".maps");
  30
  31/* map to store egress interfaces mac addresses, set the
  32 * max_entries to 1 and extend it in user sapce prog.
  33 */
  34struct {
  35        __uint(type, BPF_MAP_TYPE_ARRAY);
  36        __type(key, u32);
  37        __type(value, __be64);
  38        __uint(max_entries, 1);
  39} mac_map SEC(".maps");
  40
  41static int xdp_redirect_map(struct xdp_md *ctx, void *forward_map)
  42{
  43        long *value;
  44        u32 key = 0;
  45
  46        /* count packet in global counter */
  47        value = bpf_map_lookup_elem(&rxcnt, &key);
  48        if (value)
  49                *value += 1;
  50
  51        return bpf_redirect_map(forward_map, key,
  52                                BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS);
  53}
  54
  55SEC("xdp_redirect_general")
  56int xdp_redirect_map_general(struct xdp_md *ctx)
  57{
  58        return xdp_redirect_map(ctx, &forward_map_general);
  59}
  60
  61SEC("xdp_redirect_native")
  62int xdp_redirect_map_native(struct xdp_md *ctx)
  63{
  64        return xdp_redirect_map(ctx, &forward_map_native);
  65}
  66
  67SEC("xdp_devmap/map_prog")
  68int xdp_devmap_prog(struct xdp_md *ctx)
  69{
  70        void *data_end = (void *)(long)ctx->data_end;
  71        void *data = (void *)(long)ctx->data;
  72        u32 key = ctx->egress_ifindex;
  73        struct ethhdr *eth = data;
  74        __be64 *mac;
  75        u64 nh_off;
  76
  77        nh_off = sizeof(*eth);
  78        if (data + nh_off > data_end)
  79                return XDP_DROP;
  80
  81        mac = bpf_map_lookup_elem(&mac_map, &key);
  82        if (mac)
  83                __builtin_memcpy(eth->h_source, mac, ETH_ALEN);
  84
  85        return XDP_PASS;
  86}
  87
  88char _license[] SEC("license") = "GPL";
  89