File Index
Files and directories
Sign in
FILE

xdp_metadata.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/progs/xdp_metadata.c C
  1// SPDX-License-Identifier: GPL-2.0
  2
  3#include <vmlinux.h>
  4#include "xdp_metadata.h"
  5#include <bpf/bpf_helpers.h>
  6#include <bpf/bpf_endian.h>
  7
  8struct {
  9	__uint(type, BPF_MAP_TYPE_XSKMAP);
 10	__uint(max_entries, 4);
 11	__type(key, __u32);
 12	__type(value, __u32);
 13} xsk SEC(".maps");
 14
 15struct {
 16	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
 17	__uint(max_entries, 1);
 18	__type(key, __u32);
 19	__type(value, __u32);
 20} prog_arr SEC(".maps");
 21
 22struct {
 23	__uint(type, BPF_MAP_TYPE_DEVMAP);
 24	__uint(key_size, sizeof(__u32));
 25	__uint(value_size, sizeof(struct bpf_devmap_val));
 26	__uint(max_entries, 1);
 27} dev_map SEC(".maps");
 28
 29extern int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx,
 30					 __u64 *timestamp) __ksym;
 31extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash,
 32				    enum xdp_rss_hash_type *rss_type) __ksym;
 33extern int bpf_xdp_metadata_rx_vlan_tag(const struct xdp_md *ctx,
 34					__be16 *vlan_proto,
 35					__u16 *vlan_tci) __ksym;
 36
 37SEC("xdp")
 38int rx(struct xdp_md *ctx)
 39{
 40	void *data, *data_meta, *data_end;
 41	struct ipv6hdr *ip6h = NULL;
 42	struct ethhdr *eth = NULL;
 43	struct udphdr *udp = NULL;
 44	struct iphdr *iph = NULL;
 45	struct xdp_meta *meta;
 46	u64 timestamp = -1;
 47	int ret;
 48
 49	data = (void *)(long)ctx->data;
 50	data_end = (void *)(long)ctx->data_end;
 51	eth = data;
 52	if (eth + 1 < data_end) {
 53		if (eth->h_proto == bpf_htons(ETH_P_IP)) {
 54			iph = (void *)(eth + 1);
 55			if (iph + 1 < data_end && iph->protocol == IPPROTO_UDP)
 56				udp = (void *)(iph + 1);
 57		}
 58		if (eth->h_proto == bpf_htons(ETH_P_IPV6)) {
 59			ip6h = (void *)(eth + 1);
 60			if (ip6h + 1 < data_end && ip6h->nexthdr == IPPROTO_UDP)
 61				udp = (void *)(ip6h + 1);
 62		}
 63		if (udp && udp + 1 > data_end)
 64			udp = NULL;
 65	}
 66
 67	if (!udp)
 68		return XDP_PASS;
 69
 70	/* Forwarding UDP:8080 to AF_XDP */
 71	if (udp->dest != bpf_htons(8080))
 72		return XDP_PASS;
 73
 74	/* Reserve enough for all custom metadata. */
 75
 76	ret = bpf_xdp_adjust_meta(ctx, -(int)sizeof(struct xdp_meta));
 77	if (ret != 0)
 78		return XDP_DROP;
 79
 80	data = (void *)(long)ctx->data;
 81	data_meta = (void *)(long)ctx->data_meta;
 82
 83	if (data_meta + sizeof(struct xdp_meta) > data)
 84		return XDP_DROP;
 85
 86	meta = data_meta;
 87
 88	/* Export metadata. */
 89
 90	/* We expect veth bpf_xdp_metadata_rx_timestamp to return 0 HW
 91	 * timestamp, so put some non-zero value into AF_XDP frame for
 92	 * the userspace.
 93	 */
 94	bpf_xdp_metadata_rx_timestamp(ctx, &timestamp);
 95	if (timestamp == 0)
 96		meta->rx_timestamp = 1;
 97
 98	bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, &meta->rx_hash_type);
 99	bpf_xdp_metadata_rx_vlan_tag(ctx, &meta->rx_vlan_proto,
100				     &meta->rx_vlan_tci);
101
102	return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS);
103}
104
105SEC("xdp")
106int redirect(struct xdp_md *ctx)
107{
108	return bpf_redirect_map(&dev_map, ctx->rx_queue_index, XDP_PASS);
109}
110
111char _license[] SEC("license") = "GPL";
~/ Read-only file preview.