File Index
Files and directories
Sign in
FILE

xdp_redirect_map.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/progs/xdp_redirect_map.c C
  1// SPDX-License-Identifier: GPL-2.0
  2
  3#include <linux/if_ether.h>
  4
  5#include <linux/bpf.h>
  6#include <bpf/bpf_helpers.h>
  7#include <bpf/bpf_endian.h>
  8
  9struct {
 10	__uint(type, BPF_MAP_TYPE_DEVMAP);
 11	__uint(max_entries, 8);
 12	__uint(key_size, sizeof(int));
 13	__uint(value_size, sizeof(int));
 14} tx_port SEC(".maps");
 15
 16SEC("xdp")
 17int xdp_redirect_map_0(struct xdp_md *xdp)
 18{
 19	return bpf_redirect_map(&tx_port, 0, 0);
 20}
 21
 22SEC("xdp")
 23int xdp_redirect_map_1(struct xdp_md *xdp)
 24{
 25	return bpf_redirect_map(&tx_port, 1, 0);
 26}
 27
 28SEC("xdp")
 29int xdp_redirect_map_2(struct xdp_md *xdp)
 30{
 31	return bpf_redirect_map(&tx_port, 2, 0);
 32}
 33
 34struct {
 35	__uint(type, BPF_MAP_TYPE_ARRAY);
 36	__uint(max_entries, 3);
 37	__type(key, __u32);
 38	__type(value, __u64);
 39} rxcnt SEC(".maps");
 40
 41static int xdp_count(struct xdp_md *xdp, __u32 key)
 42{
 43	void *data_end = (void *)(long)xdp->data_end;
 44	void *data = (void *)(long)xdp->data;
 45	struct ethhdr *eth = data;
 46	__u64 *count;
 47
 48	if (data + sizeof(*eth) > data_end)
 49		return XDP_DROP;
 50
 51	if (bpf_htons(eth->h_proto) == ETH_P_IP) {
 52		/* We only count IPv4 packets */
 53		count = bpf_map_lookup_elem(&rxcnt, &key);
 54		if (count)
 55			*count += 1;
 56	}
 57
 58	return XDP_PASS;
 59}
 60
 61SEC("xdp")
 62int xdp_count_0(struct xdp_md *xdp)
 63{
 64	return xdp_count(xdp, 0);
 65}
 66
 67SEC("xdp")
 68int xdp_count_1(struct xdp_md *xdp)
 69{
 70	return xdp_count(xdp, 1);
 71}
 72
 73SEC("xdp")
 74int xdp_count_2(struct xdp_md *xdp)
 75{
 76	return xdp_count(xdp, 2);
 77}
 78
 79struct {
 80	__uint(type, BPF_MAP_TYPE_ARRAY);
 81	__uint(max_entries, 2);
 82	__type(key, __u32);
 83	__type(value, __be64);
 84} rx_mac SEC(".maps");
 85
 86static int store_mac(struct xdp_md *xdp, __u32 id)
 87{
 88	void *data_end = (void *)(long)xdp->data_end;
 89	void *data = (void *)(long)xdp->data;
 90	struct ethhdr *eth = data;
 91	__u32 key = id;
 92	__be64 mac = 0;
 93
 94	if (data + sizeof(*eth) > data_end)
 95		return XDP_DROP;
 96
 97	/* Only store IPv4 MAC to avoid being polluted by IPv6 packets */
 98	if (eth->h_proto == bpf_htons(ETH_P_IP)) {
 99		__builtin_memcpy(&mac, eth->h_source, ETH_ALEN);
100		bpf_map_update_elem(&rx_mac, &key, &mac, 0);
101		bpf_printk("%s - %x", __func__, mac);
102	}
103
104	return XDP_PASS;
105}
106
107SEC("xdp")
108int store_mac_1(struct xdp_md *xdp)
109{
110	return store_mac(xdp, 0);
111}
112
113SEC("xdp")
114int store_mac_2(struct xdp_md *xdp)
115{
116	return store_mac(xdp, 1);
117}
118
119char _license[] SEC("license") = "GPL";
~/ Read-only file preview.