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>
|
2021-01-11 18:44:18 +01:00
|
|
|
#include <iproute2/bpf_elf.h>
|
2021-01-07 18:30:53 +01:00
|
|
|
#include <xdp/parsing_helpers.h>
|
|
|
|
|
|
|
|
#include <linux/in.h>
|
2021-02-08 20:28:46 +01:00
|
|
|
#include <linux/in6.h>
|
2021-01-07 18:30:53 +01:00
|
|
|
#include <linux/if_ether.h>
|
|
|
|
#include <linux/ip.h>
|
2021-02-08 20:28:46 +01:00
|
|
|
#include <linux/ipv6.h>
|
2021-01-07 18:30:53 +01:00
|
|
|
#include <linux/tcp.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "pping.h"
|
|
|
|
#include "pping_helpers.h"
|
|
|
|
|
|
|
|
char _license[] SEC("license") = "GPL";
|
|
|
|
|
2021-01-25 20:40:57 +01:00
|
|
|
#ifdef HAVE_TC_LIBBPF /* detected by configure script in config.mk */
|
|
|
|
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-25 20:40:57 +01:00
|
|
|
__uint(max_entries, 16384);
|
|
|
|
__uint(pinning, LIBBPF_PIN_BY_NAME);
|
|
|
|
} ts_start SEC(".maps");
|
|
|
|
|
|
|
|
#else
|
2021-01-11 18:44:18 +01:00
|
|
|
struct bpf_elf_map SEC("maps") ts_start = {
|
2021-01-18 13:13:51 +01:00
|
|
|
.type = BPF_MAP_TYPE_HASH,
|
2021-02-08 20:28:46 +01:00
|
|
|
.size_key = sizeof(struct packet_id),
|
|
|
|
.size_value = sizeof(struct packet_timestamp),
|
2021-01-18 13:13:51 +01:00
|
|
|
.max_elem = 16384,
|
|
|
|
.pinning = PIN_GLOBAL_NS,
|
2021-01-07 18:30:53 +01:00
|
|
|
};
|
2021-01-25 20:40:57 +01:00
|
|
|
#endif
|
2021-01-07 18:30:53 +01:00
|
|
|
|
|
|
|
// TC-BFP for parsing TSVAL from egress traffic and add to map
|
2021-01-26 18:34:23 +01:00
|
|
|
SEC(TCBPF_PROG_SEC)
|
2021-01-07 18:30:53 +01:00
|
|
|
int tc_bpf_prog_egress(struct __sk_buff *skb)
|
|
|
|
{
|
2021-01-18 13:13:51 +01:00
|
|
|
void *data = (void *)(long)skb->data;
|
|
|
|
void *data_end = (void *)(long)skb->data_end;
|
|
|
|
|
|
|
|
int proto = -1;
|
2021-02-08 20:28:46 +01:00
|
|
|
__u32 tsval, tsecr;
|
|
|
|
|
2021-01-18 13:13:51 +01:00
|
|
|
struct hdr_cursor nh = { .pos = data };
|
|
|
|
struct ethhdr *eth;
|
|
|
|
struct iphdr *iph;
|
2021-02-08 20:28:46 +01:00
|
|
|
struct ipv6hdr *ip6h;
|
2021-01-18 13:13:51 +01:00
|
|
|
struct tcphdr *tcph;
|
2021-01-07 18:30:53 +01:00
|
|
|
|
2021-02-08 20:28:46 +01:00
|
|
|
struct packet_id p_id = { 0 };
|
|
|
|
struct packet_timestamp p_ts = { 0 };
|
|
|
|
|
|
|
|
proto = bpf_ntohs(parse_ethhdr(&nh, data_end, ð));
|
|
|
|
|
|
|
|
// Parse IPv4/6 header
|
|
|
|
if (proto == ETH_P_IP) {
|
|
|
|
p_id.flow.ipv = AF_INET;
|
|
|
|
proto = parse_iphdr(&nh, data_end, &iph);
|
|
|
|
} else if (proto == ETH_P_IPV6) {
|
|
|
|
p_id.flow.ipv = AF_INET6;
|
|
|
|
proto = parse_ip6hdr(&nh, data_end, &ip6h);
|
|
|
|
} else
|
2021-01-27 12:16:11 +01:00
|
|
|
goto end;
|
2021-02-08 20:28:46 +01:00
|
|
|
|
|
|
|
// Parse TCP timestamp
|
2021-01-18 13:13:51 +01:00
|
|
|
if (proto != IPPROTO_TCP)
|
2021-01-27 12:16:11 +01:00
|
|
|
goto end;
|
2021-02-08 20:28:46 +01:00
|
|
|
if (parse_tcphdr(&nh, data_end, &tcph) < 0)
|
2021-01-27 12:16:11 +01:00
|
|
|
goto end;
|
2021-01-18 13:13:51 +01:00
|
|
|
if (parse_tcp_ts(tcph, data_end, &tsval, &tsecr) < 0)
|
|
|
|
goto end;
|
2021-01-26 18:34:23 +01:00
|
|
|
|
2021-01-18 13:13:51 +01:00
|
|
|
// We have a TCP timestamp, try adding it to the map
|
2021-02-08 20:28:46 +01:00
|
|
|
p_id.identifier = tsval;
|
|
|
|
if (p_id.flow.ipv == AF_INET) {
|
|
|
|
map_ipv4_to_ipv6(iph->saddr, &(p_id.flow.saddr));
|
|
|
|
map_ipv4_to_ipv6(iph->daddr, &(p_id.flow.daddr));
|
|
|
|
} else { // IPv6
|
|
|
|
p_id.flow.saddr = ip6h->saddr;
|
|
|
|
p_id.flow.daddr = ip6h->daddr;
|
|
|
|
}
|
|
|
|
p_id.flow.sport = tcph->source;
|
|
|
|
p_id.flow.dport = tcph->dest;
|
|
|
|
|
|
|
|
p_ts.timestamp = bpf_ktime_get_ns(); // or bpf_ktime_get_boot_ns
|
|
|
|
bpf_map_update_elem(&ts_start, &p_id, &p_ts, BPF_NOEXIST);
|
2021-01-07 18:30:53 +01:00
|
|
|
|
2021-01-18 13:13:51 +01:00
|
|
|
end:
|
|
|
|
return BPF_OK;
|
2021-01-07 18:30:53 +01:00
|
|
|
}
|