Files
xdp-project-bpf-examples/pping/pping_kern_xdp.c
Simon Sundberg 3268ba87bb pping: Refactor TC and XDP programs
Refactor TC and XDP programs to reuse common logic for parsing
packets. Add functions for parsing packets for an identifier to
pping_helpers.h which both TC and XDP parts use. Also make it easier
to extend pping with support for new protocols, as only new parsing
functions have to be added and inserted into a single place.

Also add reserved members to end of structs in pping.h to indicate
padding.

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2021-02-09 18:09:30 +01:00

63 lines
1.8 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include "pping.h"
#include "pping_helpers.h"
char _license[] SEC("license") = "GPL";
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(key_size, sizeof(struct packet_id));
__uint(value_size, sizeof(struct packet_timestamp));
__uint(max_entries, 16384);
__uint(pinning, LIBBPF_PIN_BY_NAME);
} ts_start SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(__u32));
__uint(value_size, sizeof(__u32));
} rtt_events SEC(".maps");
// XDP program for parsing identifier in ingress traffic and check for match in map
SEC(XDP_PROG_SEC)
int xdp_prog_ingress(struct xdp_md *ctx)
{
struct packet_id p_id = { 0 };
struct packet_timestamp *p_ts;
struct rtt_event event = { 0 };
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
// saddr and daddr in reverse order of egress (source <--> dest)
if (parse_packet_identifier(data, data_end, false, &p_id,
&p_id.flow.daddr, &p_id.flow.saddr) < 0)
goto end;
p_ts = bpf_map_lookup_elem(&ts_start, &p_id);
// Only calculate RTT for first packet with matching identifer
if (p_ts && p_ts->used == 0) {
/*
* As used is not set atomically with the lookup, could
* potentially have multiple "first" packets (on different
* CPUs), but all those should then also have very similar RTT,
* so don't consider it a significant issue
*/
p_ts->used = 1;
// TODO - Optional delete of entry (if identifier is garantued unique)
__builtin_memcpy(&event.flow, &p_id.flow,
sizeof(struct network_tuple));
event.rtt = bpf_ktime_get_ns() - p_ts->timestamp;
bpf_perf_event_output(ctx, &rtt_events, BPF_F_CURRENT_CPU,
&event, sizeof(event));
}
end:
return XDP_PASS;
}