Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/ptrace.h>
0003 #include <linux/version.h>
0004 #include <uapi/linux/bpf.h>
0005 #include <bpf/bpf_helpers.h>
0006 
0007 #define SAMPLE_SIZE 64ul
0008 
0009 struct {
0010     __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
0011     __uint(key_size, sizeof(int));
0012     __uint(value_size, sizeof(u32));
0013 } my_map SEC(".maps");
0014 
0015 SEC("xdp_sample")
0016 int xdp_sample_prog(struct xdp_md *ctx)
0017 {
0018     void *data_end = (void *)(long)ctx->data_end;
0019     void *data = (void *)(long)ctx->data;
0020 
0021     /* Metadata will be in the perf event before the packet data. */
0022     struct S {
0023         u16 cookie;
0024         u16 pkt_len;
0025     } __packed metadata;
0026 
0027     if (data < data_end) {
0028         /* The XDP perf_event_output handler will use the upper 32 bits
0029          * of the flags argument as a number of bytes to include of the
0030          * packet payload in the event data. If the size is too big, the
0031          * call to bpf_perf_event_output will fail and return -EFAULT.
0032          *
0033          * See bpf_xdp_event_output in net/core/filter.c.
0034          *
0035          * The BPF_F_CURRENT_CPU flag means that the event output fd
0036          * will be indexed by the CPU number in the event map.
0037          */
0038         u64 flags = BPF_F_CURRENT_CPU;
0039         u16 sample_size;
0040         int ret;
0041 
0042         metadata.cookie = 0xdead;
0043         metadata.pkt_len = (u16)(data_end - data);
0044         sample_size = min(metadata.pkt_len, SAMPLE_SIZE);
0045         flags |= (u64)sample_size << 32;
0046 
0047         ret = bpf_perf_event_output(ctx, &my_map, flags,
0048                         &metadata, sizeof(metadata));
0049         if (ret)
0050             bpf_printk("perf_event_output failed: %d\n", ret);
0051     }
0052 
0053     return XDP_PASS;
0054 }
0055 
0056 char _license[] SEC("license") = "GPL";
0057 u32 _version SEC("version") = LINUX_VERSION_CODE;