xref: /linux/tools/testing/selftests/bpf/progs/xsk_xdp_progs.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
1f0a249dfSMagnus Karlsson // SPDX-License-Identifier: GPL-2.0
2f0a249dfSMagnus Karlsson /* Copyright (c) 2022 Intel */
3f0a249dfSMagnus Karlsson 
4f0a249dfSMagnus Karlsson #include <linux/bpf.h>
5f0a249dfSMagnus Karlsson #include <bpf/bpf_helpers.h>
6*6d198a89STushar Vyavahare #include <linux/if_ether.h>
793ba1124STushar Vyavahare #include "xsk_xdp_common.h"
8f0a249dfSMagnus Karlsson 
9f0a249dfSMagnus Karlsson struct {
10f0a249dfSMagnus Karlsson 	__uint(type, BPF_MAP_TYPE_XSKMAP);
11*6d198a89STushar Vyavahare 	__uint(max_entries, 2);
12f0a249dfSMagnus Karlsson 	__uint(key_size, sizeof(int));
13f0a249dfSMagnus Karlsson 	__uint(value_size, sizeof(int));
14f0a249dfSMagnus Karlsson } xsk SEC(".maps");
15f0a249dfSMagnus Karlsson 
1680bea9acSMagnus Karlsson static unsigned int idx;
179a321fd3STushar Vyavahare int count = 0;
1880bea9acSMagnus Karlsson 
xsk_def_prog(struct xdp_md * xdp)19f540d44eSMagnus Karlsson SEC("xdp.frags") int xsk_def_prog(struct xdp_md *xdp)
20f0a249dfSMagnus Karlsson {
21f0a249dfSMagnus Karlsson 	return bpf_redirect_map(&xsk, 0, XDP_DROP);
22f0a249dfSMagnus Karlsson }
23f0a249dfSMagnus Karlsson 
xsk_xdp_drop(struct xdp_md * xdp)24f540d44eSMagnus Karlsson SEC("xdp.frags") int xsk_xdp_drop(struct xdp_md *xdp)
2580bea9acSMagnus Karlsson {
2680bea9acSMagnus Karlsson 	/* Drop every other packet */
2780bea9acSMagnus Karlsson 	if (idx++ % 2)
2880bea9acSMagnus Karlsson 		return XDP_DROP;
2980bea9acSMagnus Karlsson 
3080bea9acSMagnus Karlsson 	return bpf_redirect_map(&xsk, 0, XDP_DROP);
3180bea9acSMagnus Karlsson }
3280bea9acSMagnus Karlsson 
xsk_xdp_populate_metadata(struct xdp_md * xdp)33f80ddbecSMagnus Karlsson SEC("xdp.frags") int xsk_xdp_populate_metadata(struct xdp_md *xdp)
349a321fd3STushar Vyavahare {
359a321fd3STushar Vyavahare 	void *data, *data_meta;
369a321fd3STushar Vyavahare 	struct xdp_info *meta;
379a321fd3STushar Vyavahare 	int err;
389a321fd3STushar Vyavahare 
399a321fd3STushar Vyavahare 	/* Reserve enough for all custom metadata. */
409a321fd3STushar Vyavahare 	err = bpf_xdp_adjust_meta(xdp, -(int)sizeof(struct xdp_info));
419a321fd3STushar Vyavahare 	if (err)
429a321fd3STushar Vyavahare 		return XDP_DROP;
439a321fd3STushar Vyavahare 
449a321fd3STushar Vyavahare 	data = (void *)(long)xdp->data;
459a321fd3STushar Vyavahare 	data_meta = (void *)(long)xdp->data_meta;
469a321fd3STushar Vyavahare 
479a321fd3STushar Vyavahare 	if (data_meta + sizeof(struct xdp_info) > data)
489a321fd3STushar Vyavahare 		return XDP_DROP;
499a321fd3STushar Vyavahare 
509a321fd3STushar Vyavahare 	meta = data_meta;
519a321fd3STushar Vyavahare 	meta->count = count++;
529a321fd3STushar Vyavahare 
539a321fd3STushar Vyavahare 	return bpf_redirect_map(&xsk, 0, XDP_DROP);
549a321fd3STushar Vyavahare }
559a321fd3STushar Vyavahare 
xsk_xdp_shared_umem(struct xdp_md * xdp)56*6d198a89STushar Vyavahare SEC("xdp") int xsk_xdp_shared_umem(struct xdp_md *xdp)
57*6d198a89STushar Vyavahare {
58*6d198a89STushar Vyavahare 	void *data = (void *)(long)xdp->data;
59*6d198a89STushar Vyavahare 	void *data_end = (void *)(long)xdp->data_end;
60*6d198a89STushar Vyavahare 	struct ethhdr *eth = data;
61*6d198a89STushar Vyavahare 
62*6d198a89STushar Vyavahare 	if (eth + 1 > data_end)
63*6d198a89STushar Vyavahare 		return XDP_DROP;
64*6d198a89STushar Vyavahare 
65*6d198a89STushar Vyavahare 	/* Redirecting packets based on the destination MAC address */
66*6d198a89STushar Vyavahare 	idx = ((unsigned int)(eth->h_dest[5])) / 2;
67*6d198a89STushar Vyavahare 	if (idx > MAX_SOCKETS)
68*6d198a89STushar Vyavahare 		return XDP_DROP;
69*6d198a89STushar Vyavahare 
70*6d198a89STushar Vyavahare 	return bpf_redirect_map(&xsk, idx, XDP_DROP);
71*6d198a89STushar Vyavahare }
72*6d198a89STushar Vyavahare 
73f0a249dfSMagnus Karlsson char _license[] SEC("license") = "GPL";
74