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