18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/ptrace.h> 38c2ecf20Sopenharmony_ci#include <linux/version.h> 48c2ecf20Sopenharmony_ci#include <uapi/linux/bpf.h> 58c2ecf20Sopenharmony_ci#include <bpf/bpf_helpers.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#define SAMPLE_SIZE 64ul 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_cistruct { 108c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); 118c2ecf20Sopenharmony_ci __uint(key_size, sizeof(int)); 128c2ecf20Sopenharmony_ci __uint(value_size, sizeof(u32)); 138c2ecf20Sopenharmony_ci} my_map SEC(".maps"); 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ciSEC("xdp_sample") 168c2ecf20Sopenharmony_ciint xdp_sample_prog(struct xdp_md *ctx) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci void *data_end = (void *)(long)ctx->data_end; 198c2ecf20Sopenharmony_ci void *data = (void *)(long)ctx->data; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci /* Metadata will be in the perf event before the packet data. */ 228c2ecf20Sopenharmony_ci struct S { 238c2ecf20Sopenharmony_ci u16 cookie; 248c2ecf20Sopenharmony_ci u16 pkt_len; 258c2ecf20Sopenharmony_ci } __packed metadata; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci if (data < data_end) { 288c2ecf20Sopenharmony_ci /* The XDP perf_event_output handler will use the upper 32 bits 298c2ecf20Sopenharmony_ci * of the flags argument as a number of bytes to include of the 308c2ecf20Sopenharmony_ci * packet payload in the event data. If the size is too big, the 318c2ecf20Sopenharmony_ci * call to bpf_perf_event_output will fail and return -EFAULT. 328c2ecf20Sopenharmony_ci * 338c2ecf20Sopenharmony_ci * See bpf_xdp_event_output in net/core/filter.c. 348c2ecf20Sopenharmony_ci * 358c2ecf20Sopenharmony_ci * The BPF_F_CURRENT_CPU flag means that the event output fd 368c2ecf20Sopenharmony_ci * will be indexed by the CPU number in the event map. 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_ci u64 flags = BPF_F_CURRENT_CPU; 398c2ecf20Sopenharmony_ci u16 sample_size; 408c2ecf20Sopenharmony_ci int ret; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci metadata.cookie = 0xdead; 438c2ecf20Sopenharmony_ci metadata.pkt_len = (u16)(data_end - data); 448c2ecf20Sopenharmony_ci sample_size = min(metadata.pkt_len, SAMPLE_SIZE); 458c2ecf20Sopenharmony_ci flags |= (u64)sample_size << 32; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci ret = bpf_perf_event_output(ctx, &my_map, flags, 488c2ecf20Sopenharmony_ci &metadata, sizeof(metadata)); 498c2ecf20Sopenharmony_ci if (ret) 508c2ecf20Sopenharmony_ci bpf_printk("perf_event_output failed: %d\n", ret); 518c2ecf20Sopenharmony_ci } 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci return XDP_PASS; 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cichar _license[] SEC("license") = "GPL"; 578c2ecf20Sopenharmony_ciu32 _version SEC("version") = LINUX_VERSION_CODE; 58