1e2a46d54SStanislav Fomichev // SPDX-License-Identifier: GPL-2.0 2e2a46d54SStanislav Fomichev 3e2a46d54SStanislav Fomichev #include <vmlinux.h> 4e2a46d54SStanislav Fomichev #include "xdp_metadata.h" 5e2a46d54SStanislav Fomichev #include <bpf/bpf_helpers.h> 6e2a46d54SStanislav Fomichev #include <bpf/bpf_endian.h> 7e2a46d54SStanislav Fomichev 8e2a46d54SStanislav Fomichev struct { 9e2a46d54SStanislav Fomichev __uint(type, BPF_MAP_TYPE_XSKMAP); 10e2a46d54SStanislav Fomichev __uint(max_entries, 4); 11e2a46d54SStanislav Fomichev __type(key, __u32); 12e2a46d54SStanislav Fomichev __type(value, __u32); 13e2a46d54SStanislav Fomichev } xsk SEC(".maps"); 14e2a46d54SStanislav Fomichev 15e2a46d54SStanislav Fomichev struct { 16e2a46d54SStanislav Fomichev __uint(type, BPF_MAP_TYPE_PROG_ARRAY); 17e2a46d54SStanislav Fomichev __uint(max_entries, 1); 18e2a46d54SStanislav Fomichev __type(key, __u32); 19e2a46d54SStanislav Fomichev __type(value, __u32); 20e2a46d54SStanislav Fomichev } prog_arr SEC(".maps"); 21e2a46d54SStanislav Fomichev 22e2a46d54SStanislav Fomichev extern int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx, 23e2a46d54SStanislav Fomichev __u64 *timestamp) __ksym; 24*0f26b74eSJesper Dangaard Brouer extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash, 25*0f26b74eSJesper Dangaard Brouer enum xdp_rss_hash_type *rss_type) __ksym; 26e2a46d54SStanislav Fomichev 27e2a46d54SStanislav Fomichev SEC("xdp") 28e2a46d54SStanislav Fomichev int rx(struct xdp_md *ctx) 29e2a46d54SStanislav Fomichev { 30e2a46d54SStanislav Fomichev void *data, *data_meta; 31e2a46d54SStanislav Fomichev struct xdp_meta *meta; 32e2a46d54SStanislav Fomichev u64 timestamp = -1; 33e2a46d54SStanislav Fomichev int ret; 34e2a46d54SStanislav Fomichev 35e2a46d54SStanislav Fomichev /* Reserve enough for all custom metadata. */ 36e2a46d54SStanislav Fomichev 37e2a46d54SStanislav Fomichev ret = bpf_xdp_adjust_meta(ctx, -(int)sizeof(struct xdp_meta)); 38e2a46d54SStanislav Fomichev if (ret != 0) 39e2a46d54SStanislav Fomichev return XDP_DROP; 40e2a46d54SStanislav Fomichev 41e2a46d54SStanislav Fomichev data = (void *)(long)ctx->data; 42e2a46d54SStanislav Fomichev data_meta = (void *)(long)ctx->data_meta; 43e2a46d54SStanislav Fomichev 44e2a46d54SStanislav Fomichev if (data_meta + sizeof(struct xdp_meta) > data) 45e2a46d54SStanislav Fomichev return XDP_DROP; 46e2a46d54SStanislav Fomichev 47e2a46d54SStanislav Fomichev meta = data_meta; 48e2a46d54SStanislav Fomichev 49e2a46d54SStanislav Fomichev /* Export metadata. */ 50e2a46d54SStanislav Fomichev 51e2a46d54SStanislav Fomichev /* We expect veth bpf_xdp_metadata_rx_timestamp to return 0 HW 52e2a46d54SStanislav Fomichev * timestamp, so put some non-zero value into AF_XDP frame for 53e2a46d54SStanislav Fomichev * the userspace. 54e2a46d54SStanislav Fomichev */ 55e2a46d54SStanislav Fomichev bpf_xdp_metadata_rx_timestamp(ctx, ×tamp); 56e2a46d54SStanislav Fomichev if (timestamp == 0) 57e2a46d54SStanislav Fomichev meta->rx_timestamp = 1; 58e2a46d54SStanislav Fomichev 59*0f26b74eSJesper Dangaard Brouer bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, &meta->rx_hash_type); 60e2a46d54SStanislav Fomichev 61e2a46d54SStanislav Fomichev return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS); 62e2a46d54SStanislav Fomichev } 63e2a46d54SStanislav Fomichev 64e2a46d54SStanislav Fomichev char _license[] SEC("license") = "GPL"; 65