162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#include <vmlinux.h> 462306a36Sopenharmony_ci#include "xdp_metadata.h" 562306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 662306a36Sopenharmony_ci#include <bpf/bpf_endian.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_cistruct { 962306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_XSKMAP); 1062306a36Sopenharmony_ci __uint(max_entries, 4); 1162306a36Sopenharmony_ci __type(key, __u32); 1262306a36Sopenharmony_ci __type(value, __u32); 1362306a36Sopenharmony_ci} xsk SEC(".maps"); 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistruct { 1662306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_PROG_ARRAY); 1762306a36Sopenharmony_ci __uint(max_entries, 1); 1862306a36Sopenharmony_ci __type(key, __u32); 1962306a36Sopenharmony_ci __type(value, __u32); 2062306a36Sopenharmony_ci} prog_arr SEC(".maps"); 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ciextern int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx, 2362306a36Sopenharmony_ci __u64 *timestamp) __ksym; 2462306a36Sopenharmony_ciextern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash, 2562306a36Sopenharmony_ci enum xdp_rss_hash_type *rss_type) __ksym; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ciSEC("xdp") 2862306a36Sopenharmony_ciint rx(struct xdp_md *ctx) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci void *data, *data_meta; 3162306a36Sopenharmony_ci struct xdp_meta *meta; 3262306a36Sopenharmony_ci u64 timestamp = -1; 3362306a36Sopenharmony_ci int ret; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci /* Reserve enough for all custom metadata. */ 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci ret = bpf_xdp_adjust_meta(ctx, -(int)sizeof(struct xdp_meta)); 3862306a36Sopenharmony_ci if (ret != 0) 3962306a36Sopenharmony_ci return XDP_DROP; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci data = (void *)(long)ctx->data; 4262306a36Sopenharmony_ci data_meta = (void *)(long)ctx->data_meta; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci if (data_meta + sizeof(struct xdp_meta) > data) 4562306a36Sopenharmony_ci return XDP_DROP; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci meta = data_meta; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci /* Export metadata. */ 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci /* We expect veth bpf_xdp_metadata_rx_timestamp to return 0 HW 5262306a36Sopenharmony_ci * timestamp, so put some non-zero value into AF_XDP frame for 5362306a36Sopenharmony_ci * the userspace. 5462306a36Sopenharmony_ci */ 5562306a36Sopenharmony_ci bpf_xdp_metadata_rx_timestamp(ctx, ×tamp); 5662306a36Sopenharmony_ci if (timestamp == 0) 5762306a36Sopenharmony_ci meta->rx_timestamp = 1; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, &meta->rx_hash_type); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS); 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 65