selftests/bpf: Optionally select broadcasting flags

Broadcasting flags are hardcoded for each kind for protocol.

Create a redirect_flags map that allows to select the broadcasting flags
to use in the bpf_redirect_map(). The protocol ID is used as a key.
Set the old hardcoded values as default if the map isn't filled by the
BPF caller.

Signed-off-by: Bastien Curutchet (eBPF Foundation) <bastien.curutchet@bootlin.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250212-redirect-multi-v5-3-fd0d39fca6e6@bootlin.com
This commit is contained in:
Bastien Curutchet (eBPF Foundation)
2025-02-12 12:11:11 +01:00
committed by Martin KaFai Lau
parent 19a9484c1b
commit 09c8bb1fae

View File

@@ -34,6 +34,14 @@ struct {
__uint(max_entries, 128);
} mac_map SEC(".maps");
/* map to store redirect flags for each protocol*/
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, __u16);
__type(value, __u64);
__uint(max_entries, 16);
} redirect_flags SEC(".maps");
SEC("xdp")
int xdp_redirect_map_multi_prog(struct xdp_md *ctx)
{
@@ -41,25 +49,34 @@ int xdp_redirect_map_multi_prog(struct xdp_md *ctx)
void *data = (void *)(long)ctx->data;
int if_index = ctx->ingress_ifindex;
struct ethhdr *eth = data;
__u64 *flags_from_map;
__u16 h_proto;
__u64 nh_off;
__u64 flags;
nh_off = sizeof(*eth);
if (data + nh_off > data_end)
return XDP_DROP;
h_proto = eth->h_proto;
h_proto = bpf_htons(eth->h_proto);
/* Using IPv4 for (BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS) testing */
if (h_proto == bpf_htons(ETH_P_IP))
return bpf_redirect_map(&map_all, 0,
BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS);
/* Using IPv6 for none flag testing */
else if (h_proto == bpf_htons(ETH_P_IPV6))
return bpf_redirect_map(&map_all, if_index, 0);
/* All others for BPF_F_BROADCAST testing */
else
return bpf_redirect_map(&map_all, 0, BPF_F_BROADCAST);
flags_from_map = bpf_map_lookup_elem(&redirect_flags, &h_proto);
/* Default flags for IPv4 : (BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS) */
if (h_proto == ETH_P_IP) {
flags = flags_from_map ? *flags_from_map : BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS;
return bpf_redirect_map(&map_all, 0, flags);
}
/* Default flags for IPv6 : 0 */
if (h_proto == ETH_P_IPV6) {
flags = flags_from_map ? *flags_from_map : 0;
return bpf_redirect_map(&map_all, if_index, flags);
}
/* Default flags for others BPF_F_BROADCAST : 0 */
else {
flags = flags_from_map ? *flags_from_map : BPF_F_BROADCAST;
return bpf_redirect_map(&map_all, 0, flags);
}
}
/* The following 2 progs are for 2nd devmap prog testing */