1d39aec79SDavid Ahern // SPDX-License-Identifier: GPL-2.0
2d39aec79SDavid Ahern 
3d39aec79SDavid Ahern #include "vmlinux.h"
4d39aec79SDavid Ahern #include <bpf/bpf_helpers.h>
5d39aec79SDavid Ahern 
6d39aec79SDavid Ahern struct {
7d39aec79SDavid Ahern 	__uint(type, BPF_MAP_TYPE_DEVMAP);
8d39aec79SDavid Ahern 	__uint(key_size, sizeof(__u32));
9d39aec79SDavid Ahern 	__uint(value_size, sizeof(struct bpf_devmap_val));
10d39aec79SDavid Ahern 	__uint(max_entries, 4);
11d39aec79SDavid Ahern } dm_ports SEC(".maps");
12d39aec79SDavid Ahern 
13d39aec79SDavid Ahern SEC("xdp_redir")
14d39aec79SDavid Ahern int xdp_redir_prog(struct xdp_md *ctx)
15d39aec79SDavid Ahern {
16d39aec79SDavid Ahern 	return bpf_redirect_map(&dm_ports, 1, 0);
17d39aec79SDavid Ahern }
18d39aec79SDavid Ahern 
19d39aec79SDavid Ahern /* invalid program on DEVMAP entry;
20d39aec79SDavid Ahern  * SEC name means expected attach type not set
21d39aec79SDavid Ahern  */
22d39aec79SDavid Ahern SEC("xdp_dummy")
23d39aec79SDavid Ahern int xdp_dummy_prog(struct xdp_md *ctx)
24d39aec79SDavid Ahern {
25d39aec79SDavid Ahern 	return XDP_PASS;
26d39aec79SDavid Ahern }
27d39aec79SDavid Ahern 
28d39aec79SDavid Ahern /* valid program on DEVMAP entry via SEC name;
29d39aec79SDavid Ahern  * has access to egress and ingress ifindex
30d39aec79SDavid Ahern  */
31d39aec79SDavid Ahern SEC("xdp_devmap")
32d39aec79SDavid Ahern int xdp_dummy_dm(struct xdp_md *ctx)
33d39aec79SDavid Ahern {
34d39aec79SDavid Ahern 	char fmt[] = "devmap redirect: dev %u -> dev %u len %u\n";
35d39aec79SDavid Ahern 	void *data_end = (void *)(long)ctx->data_end;
36d39aec79SDavid Ahern 	void *data = (void *)(long)ctx->data;
37d39aec79SDavid Ahern 	unsigned int len = data_end - data;
38d39aec79SDavid Ahern 
39d39aec79SDavid Ahern 	bpf_trace_printk(fmt, sizeof(fmt),
40d39aec79SDavid Ahern 			 ctx->ingress_ifindex, ctx->egress_ifindex, len);
41d39aec79SDavid Ahern 
42d39aec79SDavid Ahern 	return XDP_PASS;
43d39aec79SDavid Ahern }
44d39aec79SDavid Ahern char _license[] SEC("license") = "GPL";
45