Toke Høiland-Jørgensen | 1e54ad2 | 2018-06-25 14:25:02 +0200 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/ptrace.h> |
| 3 | #include <linux/version.h> |
| 4 | #include <uapi/linux/bpf.h> |
Toke Høiland-Jørgensen | 7cf245a | 2020-01-20 14:06:49 +0100 | [diff] [blame] | 5 | #include <bpf/bpf_helpers.h> |
Toke Høiland-Jørgensen | 1e54ad2 | 2018-06-25 14:25:02 +0200 | [diff] [blame] | 6 | |
| 7 | #define SAMPLE_SIZE 64ul |
Toke Høiland-Jørgensen | 1e54ad2 | 2018-06-25 14:25:02 +0200 | [diff] [blame] | 8 | |
Daniel T. Lee | 321f632 | 2020-10-11 03:17:34 +0900 | [diff] [blame] | 9 | struct { |
| 10 | __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); |
| 11 | __uint(key_size, sizeof(int)); |
| 12 | __uint(value_size, sizeof(u32)); |
| 13 | } my_map SEC(".maps"); |
Toke Høiland-Jørgensen | 1e54ad2 | 2018-06-25 14:25:02 +0200 | [diff] [blame] | 14 | |
| 15 | SEC("xdp_sample") |
| 16 | int xdp_sample_prog(struct xdp_md *ctx) |
| 17 | { |
| 18 | void *data_end = (void *)(long)ctx->data_end; |
| 19 | void *data = (void *)(long)ctx->data; |
| 20 | |
| 21 | /* Metadata will be in the perf event before the packet data. */ |
| 22 | struct S { |
| 23 | u16 cookie; |
| 24 | u16 pkt_len; |
| 25 | } __packed metadata; |
| 26 | |
| 27 | if (data < data_end) { |
| 28 | /* The XDP perf_event_output handler will use the upper 32 bits |
| 29 | * of the flags argument as a number of bytes to include of the |
| 30 | * packet payload in the event data. If the size is too big, the |
| 31 | * call to bpf_perf_event_output will fail and return -EFAULT. |
| 32 | * |
| 33 | * See bpf_xdp_event_output in net/core/filter.c. |
| 34 | * |
| 35 | * The BPF_F_CURRENT_CPU flag means that the event output fd |
| 36 | * will be indexed by the CPU number in the event map. |
| 37 | */ |
| 38 | u64 flags = BPF_F_CURRENT_CPU; |
| 39 | u16 sample_size; |
| 40 | int ret; |
| 41 | |
| 42 | metadata.cookie = 0xdead; |
| 43 | metadata.pkt_len = (u16)(data_end - data); |
| 44 | sample_size = min(metadata.pkt_len, SAMPLE_SIZE); |
| 45 | flags |= (u64)sample_size << 32; |
| 46 | |
| 47 | ret = bpf_perf_event_output(ctx, &my_map, flags, |
| 48 | &metadata, sizeof(metadata)); |
| 49 | if (ret) |
| 50 | bpf_printk("perf_event_output failed: %d\n", ret); |
| 51 | } |
| 52 | |
| 53 | return XDP_PASS; |
| 54 | } |
| 55 | |
| 56 | char _license[] SEC("license") = "GPL"; |
| 57 | u32 _version SEC("version") = LINUX_VERSION_CODE; |