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 8 struct { 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 15 struct { 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 22 extern int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx, 23 __u64 *timestamp) __ksym; 24 extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, 25 __u32 *hash) __ksym; 26 27 SEC("xdp") 28 int rx(struct xdp_md *ctx) 29 { 30 void *data, *data_meta; 31 struct xdp_meta *meta; 32 u64 timestamp = -1; 33 int ret; 34 35 /* Reserve enough for all custom metadata. */ 36 37 ret = bpf_xdp_adjust_meta(ctx, -(int)sizeof(struct xdp_meta)); 38 if (ret != 0) 39 return XDP_DROP; 40 41 data = (void *)(long)ctx->data; 42 data_meta = (void *)(long)ctx->data_meta; 43 44 if (data_meta + sizeof(struct xdp_meta) > data) 45 return XDP_DROP; 46 47 meta = data_meta; 48 49 /* Export metadata. */ 50 51 /* We expect veth bpf_xdp_metadata_rx_timestamp to return 0 HW 52 * timestamp, so put some non-zero value into AF_XDP frame for 53 * the userspace. 54 */ 55 bpf_xdp_metadata_rx_timestamp(ctx, ×tamp); 56 if (timestamp == 0) 57 meta->rx_timestamp = 1; 58 59 bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash); 60 61 return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS); 62 } 63 64 char _license[] SEC("license") = "GPL"; 65