2021-01-18 13:13:51 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2021-01-07 18:30:53 +01:00
|
|
|
#include <linux/bpf.h>
|
|
|
|
|
#include <bpf/bpf_helpers.h>
|
|
|
|
|
|
|
|
|
|
#include "pping.h"
|
|
|
|
|
#include "pping_helpers.h"
|
|
|
|
|
|
|
|
|
|
char _license[] SEC("license") = "GPL";
|
|
|
|
|
|
2021-01-20 19:49:51 +01:00
|
|
|
struct {
|
|
|
|
|
__uint(type, BPF_MAP_TYPE_HASH);
|
2021-02-08 20:28:46 +01:00
|
|
|
__uint(key_size, sizeof(struct packet_id));
|
|
|
|
|
__uint(value_size, sizeof(struct packet_timestamp));
|
2021-01-20 19:49:51 +01:00
|
|
|
__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");
|
2021-01-18 13:13:51 +01:00
|
|
|
|
2021-02-09 18:09:30 +01:00
|
|
|
// XDP program for parsing identifier in ingress traffic and check for match in map
|
2021-01-26 18:34:23 +01:00
|
|
|
SEC(XDP_PROG_SEC)
|
2021-01-07 18:30:53 +01:00
|
|
|
int xdp_prog_ingress(struct xdp_md *ctx)
|
|
|
|
|
{
|
2021-02-08 20:28:46 +01:00
|
|
|
struct packet_id p_id = { 0 };
|
|
|
|
|
struct packet_timestamp *p_ts;
|
|
|
|
|
struct rtt_event event = { 0 };
|
|
|
|
|
|
2021-02-09 18:09:30 +01:00
|
|
|
void *data = (void *)(long)ctx->data;
|
|
|
|
|
void *data_end = (void *)(long)ctx->data_end;
|
2021-02-08 20:28:46 +01:00
|
|
|
|
2021-02-12 11:40:43 +01:00
|
|
|
if (parse_packet_identifier(data, data_end, false, &p_id) < 0)
|
2021-01-27 12:16:11 +01:00
|
|
|
goto end;
|
2021-02-08 20:28:46 +01:00
|
|
|
|
|
|
|
|
p_ts = bpf_map_lookup_elem(&ts_start, &p_id);
|
2021-01-26 18:34:23 +01:00
|
|
|
|
2021-02-09 18:09:30 +01:00
|
|
|
// Only calculate RTT for first packet with matching identifer
|
2021-02-08 20:28:46 +01:00
|
|
|
if (p_ts && p_ts->used == 0) {
|
2021-01-18 13:13:51 +01:00
|
|
|
/*
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2021-02-08 20:28:46 +01:00
|
|
|
p_ts->used = 1;
|
|
|
|
|
// TODO - Optional delete of entry (if identifier is garantued unique)
|
2021-01-07 18:30:53 +01:00
|
|
|
|
2021-02-09 18:09:30 +01:00
|
|
|
__builtin_memcpy(&event.flow, &p_id.flow,
|
|
|
|
|
sizeof(struct network_tuple));
|
2021-02-08 20:28:46 +01:00
|
|
|
event.rtt = bpf_ktime_get_ns() - p_ts->timestamp;
|
2021-01-18 13:13:51 +01:00
|
|
|
bpf_perf_event_output(ctx, &rtt_events, BPF_F_CURRENT_CPU,
|
|
|
|
|
&event, sizeof(event));
|
|
|
|
|
}
|
2021-01-26 18:34:23 +01:00
|
|
|
|
2021-01-18 13:13:51 +01:00
|
|
|
end:
|
|
|
|
|
return XDP_PASS;
|
2021-01-07 18:30:53 +01:00
|
|
|
}
|