Subject: Re: Allow bpf_perf_event_output to access packet data

From: Jakub Kicinski <[email-masked]>
Date: Mon, 10 Sep 2018 10:26:42 +0200

On Fri, 7 Sep 2018 15:56:15 +0100, Lorenz Bauer wrote:
> Hello list,
> 
> I'm attempting to use bpf_perf_event_output to do packet sampling from XDP.
> 
> The code basically runs before our other XDP code, does a
> perf_event_output with the full packet (for now) and then tail calls
> into DDoS mitigation, etc.
> 
> I've just discovered that perf_event_output isn't allowed to access
> packet data by the verifier. Is this something that could be allowed?

Hi Lorenz!

The amount of packet data to output is controlled by high bits of the
"flags" parameter.  This is a trivial sample:

struct bpf_map_def SEC("maps") pa = {
	.type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
	.key_size = sizeof(int),
	.value_size = sizeof(int),
	.max_entries = 64,
};

int xdp_prog1(struct xdp_md *xdp)
{
	int key = 0;

	bpf_perf_event_output(xdp, &pa, 0x20ffffffffULL, &key, 0);

	return XDP_PASS;
}

The 0x20ffffffffULL will mean use the index in the map for current CPU
(0xffffffff), and output 32 bytes of the context (0x20 << 32).  For
networking programs context means the packet (slightly confusingly).

These are the relevant defines from bpf.h:

/* BPF_FUNC_perf_event_output, BPF_FUNC_perf_event_read and
 * BPF_FUNC_perf_event_read_value flags.
 */
#define BPF_F_INDEX_MASK		0xffffffffULL
#define BPF_F_CURRENT_CPU		BPF_F_INDEX_MASK
/* BPF_FUNC_perf_event_output for sk_buff input context. */
#define BPF_F_CTXLEN_MASK		(0xfffffULL << 32)

Also check out:

bpftool map event_pipe id $ID

For simple way to dump the events in user space.