2021-01-18 13:13:51 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2021-02-09 18:09:30 +01:00
|
|
|
#include <linux/bpf.h>
|
2021-04-15 14:13:54 +02:00
|
|
|
#include <bpf/bpf_helpers.h>
|
2021-12-08 10:06:30 +01:00
|
|
|
#include <linux/pkt_cls.h>
|
2021-02-09 18:09:30 +01:00
|
|
|
#include <linux/in.h>
|
2021-02-08 20:28:46 +01:00
|
|
|
#include <linux/in6.h>
|
2021-02-09 18:09:30 +01:00
|
|
|
#include <linux/if_ether.h>
|
|
|
|
#include <linux/ip.h>
|
|
|
|
#include <linux/ipv6.h>
|
2021-01-26 18:34:23 +01:00
|
|
|
#include <linux/tcp.h>
|
2021-12-08 10:13:50 +01:00
|
|
|
#include <linux/icmp.h>
|
|
|
|
#include <linux/icmpv6.h>
|
2021-02-09 18:09:30 +01:00
|
|
|
#include <stdbool.h>
|
2023-07-04 17:34:41 +02:00
|
|
|
#include <errno.h>
|
2021-04-15 14:13:54 +02:00
|
|
|
|
2021-04-22 17:51:49 +02:00
|
|
|
// overwrite xdp/parsing_helpers.h value to avoid hitting verifier limit
|
|
|
|
#ifdef IPV6_EXT_MAX_CHAIN
|
|
|
|
#undef IPV6_EXT_MAX_CHAIN
|
|
|
|
#endif
|
|
|
|
#define IPV6_EXT_MAX_CHAIN 3
|
|
|
|
|
|
|
|
#include <xdp/parsing_helpers.h>
|
2021-02-08 20:28:46 +01:00
|
|
|
#include "pping.h"
|
2022-02-17 14:01:08 +01:00
|
|
|
#include "pping_debug_cleanup.h"
|
2021-01-26 18:34:23 +01:00
|
|
|
|
2022-04-14 21:27:07 +02:00
|
|
|
#ifndef AF_INET
|
2021-02-09 13:00:28 +01:00
|
|
|
#define AF_INET 2
|
2022-04-14 21:27:07 +02:00
|
|
|
#endif
|
|
|
|
#ifndef AF_INET6
|
2021-02-09 13:00:28 +01:00
|
|
|
#define AF_INET6 10
|
2022-04-14 21:27:07 +02:00
|
|
|
#endif
|
2021-01-07 18:30:53 +01:00
|
|
|
#define MAX_TCP_OPTIONS 10
|
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
// Mask for IPv6 flowlabel + traffic class - used in fib lookup
|
|
|
|
#define IPV6_FLOWINFO_MASK __cpu_to_be32(0x0FFFFFFF)
|
|
|
|
|
2022-02-03 15:51:22 +01:00
|
|
|
// Emit a warning max once per second when failing to add entry to map
|
|
|
|
#define WARN_MAP_FULL_INTERVAL 1000000000UL
|
|
|
|
|
2022-03-09 19:28:05 +01:00
|
|
|
// Time before map entry is considered old and can safetly be removed
|
2022-02-17 14:11:40 +01:00
|
|
|
#define TIMESTAMP_LIFETIME (10 * NS_PER_SECOND) // Clear any timestamp older than this
|
|
|
|
#define TIMESTAMP_RTT_LIFETIME 8 // Clear timestamp once it is this many times older than RTT
|
|
|
|
#define FLOW_LIFETIME (300 * NS_PER_SECOND) // Clear any flow that's been inactive this long
|
|
|
|
#define ICMP_FLOW_LIFETIME (30 * NS_PER_SECOND) // Clear any ICMP flows if they're inactive this long
|
|
|
|
#define UNOPENED_FLOW_LIFETIME (30 * NS_PER_SECOND) // Clear out flows that have not seen a response after this long
|
2022-03-09 19:28:05 +01:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
#define MAX_MEMCMP_SIZE 128
|
|
|
|
|
2022-03-09 19:28:05 +01:00
|
|
|
/*
|
|
|
|
* Structs for map iteration programs
|
|
|
|
* Copied from /tools/testing/selftest/bpf/progs/bpf_iter.h
|
|
|
|
*/
|
|
|
|
struct bpf_iter_meta {
|
|
|
|
struct seq_file *seq;
|
|
|
|
__u64 session_id;
|
|
|
|
__u64 seq_num;
|
|
|
|
} __attribute__((preserve_access_index));
|
|
|
|
|
|
|
|
struct bpf_iter__bpf_map_elem {
|
|
|
|
struct bpf_iter_meta *meta;
|
|
|
|
struct bpf_map *map;
|
|
|
|
void *key;
|
|
|
|
void *value;
|
|
|
|
};
|
|
|
|
|
2021-02-12 18:31:30 +01:00
|
|
|
/*
|
|
|
|
* This struct keeps track of the data and data_end pointers from the xdp_md or
|
|
|
|
* __skb_buff contexts, as well as a currently parsed to position kept in nh.
|
2021-02-16 12:34:19 +01:00
|
|
|
* Additionally, it also keeps the length of the entire packet, which together
|
|
|
|
* with the other members can be used to determine ex. how much data each
|
|
|
|
* header encloses.
|
2021-02-12 18:31:30 +01:00
|
|
|
*/
|
|
|
|
struct parsing_context {
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
void *data; // Start of eth hdr
|
|
|
|
void *data_end; // End of safe acessible area
|
|
|
|
struct hdr_cursor nh; // Position to parse next
|
|
|
|
__u32 pkt_len; // Full packet length (headers+data)
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Struct filled in by parse_packet_id.
|
|
|
|
*
|
|
|
|
* Note: As long as parse_packet_id is successful, the flow-parts of pid
|
|
|
|
* and reply_pid should be valid, regardless of value for pid_valid and
|
|
|
|
* reply_pid valid. The *pid_valid members are there to indicate that the
|
|
|
|
* identifier part of *pid are valid and can be used for timestamping/lookup.
|
|
|
|
* The reason for not keeping the flow parts as an entirely separate members
|
|
|
|
* is to save some performance by avoid doing a copy for lookup/insertion
|
|
|
|
* in the packet_ts map.
|
|
|
|
*/
|
|
|
|
struct packet_info {
|
|
|
|
__u64 time; // Arrival time of packet
|
2023-04-05 16:35:03 +02:00
|
|
|
__u32 pkt_len; // Size of packet (including headers)
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
__u32 payload; // Size of packet data (excluding headers)
|
2022-03-22 13:24:09 +01:00
|
|
|
struct packet_id pid; // flow + identifier to timestamp (ex. TSval)
|
|
|
|
struct packet_id reply_pid; // rev. flow + identifier to match against (ex. TSecr)
|
2022-05-31 21:19:19 +02:00
|
|
|
__u32 ingress_ifindex; // Interface packet arrived on (if is_ingress, otherwise not valid)
|
2022-06-21 17:33:58 +02:00
|
|
|
union { // The IP-level "type of service" (DSCP for IPv4, traffic class + flow label for IPv6)
|
|
|
|
__u8 ipv4_tos;
|
|
|
|
__be32 ipv6_tos;
|
|
|
|
} ip_tos;
|
|
|
|
__u16 ip_len; // The IPv4 total length or IPv6 payload length
|
2022-05-31 21:19:19 +02:00
|
|
|
bool is_ingress; // Packet on egress or ingress?
|
2022-03-22 17:59:18 +01:00
|
|
|
bool pid_flow_is_dfkey; // Used to determine which member of dualflow state to use for forward direction
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
bool pid_valid; // identifier can be used to timestamp packet
|
|
|
|
bool reply_pid_valid; // reply_identifier can be used to match packet
|
|
|
|
enum flow_event_type event_type; // flow event triggered by packet
|
|
|
|
enum flow_event_reason event_reason; // reason for triggering flow event
|
2022-11-04 13:41:47 +01:00
|
|
|
bool wait_first_edge; // Do we need to wait for the first identifier change before timestamping?
|
2021-02-12 18:31:30 +01:00
|
|
|
};
|
|
|
|
|
2022-03-22 13:24:09 +01:00
|
|
|
/*
|
|
|
|
* Struct filled in by protocol id parsers (ex. parse_tcp_identifier)
|
|
|
|
*/
|
|
|
|
struct protocol_info {
|
|
|
|
__u32 pid;
|
|
|
|
__u32 reply_pid;
|
|
|
|
bool pid_valid;
|
|
|
|
bool reply_pid_valid;
|
|
|
|
enum flow_event_type event_type;
|
|
|
|
enum flow_event_reason event_reason;
|
2022-11-04 13:41:47 +01:00
|
|
|
bool wait_first_edge;
|
2022-03-22 13:24:09 +01:00
|
|
|
};
|
|
|
|
|
2021-04-15 14:13:54 +02:00
|
|
|
char _license[] SEC("license") = "GPL";
|
|
|
|
// Global config struct - set from userspace
|
|
|
|
static volatile const struct bpf_config config = {};
|
2022-02-03 15:51:22 +01:00
|
|
|
static volatile __u64 last_warn_time[2] = { 0 };
|
|
|
|
|
2023-10-17 16:23:51 +02:00
|
|
|
// Keep an empty aggregated_stats as a global variable to use as a template
|
2023-07-04 17:34:41 +02:00
|
|
|
// when creating new entries. That way, it won't have to be allocated on stack
|
|
|
|
// (where it won't fit anyways) and initialized each time during run time.
|
2023-10-17 16:23:51 +02:00
|
|
|
static struct aggregated_stats empty_stats = { 0 };
|
2023-07-04 17:34:41 +02:00
|
|
|
|
2021-03-22 12:23:27 +01:00
|
|
|
|
2021-04-15 14:13:54 +02:00
|
|
|
// Map definitions
|
2021-03-02 17:40:51 +01:00
|
|
|
struct {
|
|
|
|
__uint(type, BPF_MAP_TYPE_HASH);
|
|
|
|
__type(key, struct packet_id);
|
|
|
|
__type(value, __u64);
|
2023-05-30 17:36:26 +02:00
|
|
|
__uint(max_entries, MAP_TIMESTAMP_SIZE);
|
2021-04-15 14:13:54 +02:00
|
|
|
} packet_ts SEC(".maps");
|
2021-03-02 17:40:51 +01:00
|
|
|
|
2021-03-09 19:58:42 +01:00
|
|
|
struct {
|
|
|
|
__uint(type, BPF_MAP_TYPE_HASH);
|
|
|
|
__type(key, struct network_tuple);
|
2022-03-22 17:59:18 +01:00
|
|
|
__type(value, struct dual_flow_state);
|
2023-05-30 17:36:26 +02:00
|
|
|
__uint(max_entries, MAP_FLOWSTATE_SIZE);
|
2021-03-09 19:58:42 +01:00
|
|
|
} flow_state SEC(".maps");
|
|
|
|
|
2021-04-15 14:13:54 +02:00
|
|
|
struct {
|
|
|
|
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
|
|
|
|
__uint(key_size, sizeof(__u32));
|
|
|
|
__uint(value_size, sizeof(__u32));
|
2021-06-22 15:22:11 +02:00
|
|
|
} events SEC(".maps");
|
2021-04-15 14:13:54 +02:00
|
|
|
|
2023-07-04 17:34:41 +02:00
|
|
|
struct {
|
|
|
|
__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
|
|
|
|
__type(key, __u32);
|
2023-10-17 16:23:51 +02:00
|
|
|
__type(value, struct aggregated_stats);
|
2023-07-04 17:34:41 +02:00
|
|
|
__uint(max_entries, MAP_AGGREGATION_SIZE);
|
2023-07-04 19:53:26 +02:00
|
|
|
} map_v4_agg1 SEC(".maps");
|
|
|
|
|
|
|
|
struct {
|
|
|
|
__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
|
|
|
|
__type(key, __u32);
|
2023-10-17 16:23:51 +02:00
|
|
|
__type(value, struct aggregated_stats);
|
2023-07-04 19:53:26 +02:00
|
|
|
__uint(max_entries, MAP_AGGREGATION_SIZE);
|
|
|
|
} map_v4_agg2 SEC(".maps");
|
|
|
|
|
|
|
|
struct {
|
|
|
|
__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
|
|
|
|
__type(key, __u64);
|
2023-10-17 16:23:51 +02:00
|
|
|
__type(value, struct aggregated_stats);
|
2023-07-04 19:53:26 +02:00
|
|
|
__uint(max_entries, MAP_AGGREGATION_SIZE);
|
|
|
|
} map_v6_agg1 SEC(".maps");
|
2023-07-04 17:34:41 +02:00
|
|
|
|
|
|
|
struct {
|
|
|
|
__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
|
|
|
|
__type(key, __u64);
|
2023-10-17 16:23:51 +02:00
|
|
|
__type(value, struct aggregated_stats);
|
2023-07-04 17:34:41 +02:00
|
|
|
__uint(max_entries, MAP_AGGREGATION_SIZE);
|
2023-07-04 19:53:26 +02:00
|
|
|
} map_v6_agg2 SEC(".maps");
|
|
|
|
|
|
|
|
struct {
|
|
|
|
__uint(type, BPF_MAP_TYPE_ARRAY);
|
|
|
|
__type(key, __u32);
|
|
|
|
__type(value, __u32);
|
|
|
|
__uint(max_entries, 1);
|
|
|
|
} map_active_agg_instance SEC(".maps");
|
2023-07-04 17:34:41 +02:00
|
|
|
|
2022-02-17 14:01:08 +01:00
|
|
|
|
2021-04-15 14:13:54 +02:00
|
|
|
// Help functions
|
|
|
|
|
2021-02-08 20:28:46 +01:00
|
|
|
/*
|
2021-02-16 12:34:19 +01:00
|
|
|
* Maps an IPv4 address into an IPv6 address according to RFC 4291 sec 2.5.5.2
|
2021-02-08 20:28:46 +01:00
|
|
|
*/
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
static void map_ipv4_to_ipv6(struct in6_addr *ipv6, __be32 ipv4)
|
2021-01-07 18:30:53 +01:00
|
|
|
{
|
2021-03-22 12:23:27 +01:00
|
|
|
__builtin_memset(&ipv6->in6_u.u6_addr8[0], 0x00, 10);
|
|
|
|
__builtin_memset(&ipv6->in6_u.u6_addr8[10], 0xff, 2);
|
2021-02-08 20:28:46 +01:00
|
|
|
ipv6->in6_u.u6_addr32[3] = ipv4;
|
2021-01-07 18:30:53 +01:00
|
|
|
}
|
2021-01-26 18:34:23 +01:00
|
|
|
|
2022-06-21 17:33:58 +02:00
|
|
|
static __be32 ipv4_from_ipv6(struct in6_addr *ipv6)
|
|
|
|
{
|
|
|
|
return ipv6->in6_u.u6_addr32[3];
|
|
|
|
}
|
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
/*
|
|
|
|
* Returns the number of unparsed bytes left in the packet (bytes after nh.pos)
|
|
|
|
*/
|
|
|
|
static __u32 remaining_pkt_payload(struct parsing_context *ctx)
|
|
|
|
{
|
|
|
|
// pkt_len - (pos - data) fails because compiler transforms it to pkt_len - pos + data (pkt_len - pos not ok because value - pointer)
|
|
|
|
// data + pkt_len - pos fails on (data+pkt_len) - pos due to math between pkt_pointer and unbounded register
|
|
|
|
__u32 parsed_bytes = ctx->nh.pos - ctx->data;
|
|
|
|
return parsed_bytes < ctx->pkt_len ? ctx->pkt_len - parsed_bytes : 0;
|
|
|
|
}
|
|
|
|
|
2022-03-09 19:28:05 +01:00
|
|
|
/*
|
|
|
|
* Convenience function for getting the corresponding reverse flow.
|
|
|
|
* PPing needs to keep track of flow in both directions, and sometimes
|
|
|
|
* also needs to reverse the flow to report the "correct" (consistent
|
|
|
|
* with Kathie's PPing) src and dest address.
|
|
|
|
*/
|
|
|
|
static void reverse_flow(struct network_tuple *dest, struct network_tuple *src)
|
|
|
|
{
|
|
|
|
dest->ipv = src->ipv;
|
|
|
|
dest->proto = src->proto;
|
|
|
|
dest->saddr = src->daddr;
|
|
|
|
dest->daddr = src->saddr;
|
|
|
|
dest->reserved = 0;
|
|
|
|
}
|
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
/*
|
|
|
|
* Can't seem to get __builtin_memcmp to work, so hacking my own
|
|
|
|
*
|
|
|
|
* Based on https://githubhot.com/repo/iovisor/bcc/issues/3559,
|
|
|
|
* __builtin_memcmp should work constant size but I still get the "failed to
|
|
|
|
* find BTF for extern" error.
|
|
|
|
*/
|
|
|
|
static int my_memcmp(const void *s1_, const void *s2_, __u32 size)
|
|
|
|
{
|
|
|
|
const __u8 *s1 = s1_, *s2 = s2_;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_MEMCMP_SIZE && i < size; i++) {
|
|
|
|
if (s1[i] != s2[i])
|
|
|
|
return s1[i] > s2[i] ? 1 : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool is_dualflow_key(struct network_tuple *flow)
|
|
|
|
{
|
|
|
|
return my_memcmp(&flow->saddr, &flow->daddr, sizeof(flow->saddr)) <= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void make_dualflow_key(struct network_tuple *key,
|
|
|
|
struct network_tuple *flow)
|
|
|
|
{
|
|
|
|
if (is_dualflow_key(flow))
|
|
|
|
*key = *flow;
|
|
|
|
else
|
|
|
|
reverse_flow(key, flow);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct flow_state *fstate_from_dfkey(struct dual_flow_state *df_state,
|
|
|
|
bool is_dfkey)
|
|
|
|
{
|
|
|
|
return is_dfkey ? &df_state->dir1 : &df_state->dir2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the flow state for flow-direction from df_state
|
|
|
|
*
|
|
|
|
* Note: Does not validate that any of the entries in df_state actually matches
|
|
|
|
* flow, just selects the direction in df_state that best fits the flow.
|
|
|
|
*/
|
|
|
|
static struct flow_state *
|
|
|
|
get_flowstate_from_dualflow(struct dual_flow_state *df_state,
|
|
|
|
struct network_tuple *flow)
|
|
|
|
{
|
|
|
|
return fstate_from_dfkey(df_state, is_dualflow_key(flow));
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct flow_state *
|
|
|
|
get_flowstate_from_packet(struct dual_flow_state *df_state,
|
|
|
|
struct packet_info *p_info)
|
|
|
|
{
|
|
|
|
return fstate_from_dfkey(df_state, p_info->pid_flow_is_dfkey);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct flow_state *
|
|
|
|
get_reverse_flowstate_from_packet(struct dual_flow_state *df_state,
|
|
|
|
struct packet_info *p_info)
|
|
|
|
{
|
|
|
|
return fstate_from_dfkey(df_state, !p_info->pid_flow_is_dfkey);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct network_tuple *
|
|
|
|
get_dualflow_key_from_packet(struct packet_info *p_info)
|
|
|
|
{
|
|
|
|
return p_info->pid_flow_is_dfkey ? &p_info->pid.flow :
|
|
|
|
&p_info->reply_pid.flow;
|
|
|
|
}
|
|
|
|
|
2021-01-18 18:08:35 +01:00
|
|
|
/*
|
2021-01-26 18:34:23 +01:00
|
|
|
* Parses the TSval and TSecr values from the TCP options field. If sucessful
|
|
|
|
* the TSval and TSecr values will be stored at tsval and tsecr (in network
|
2021-01-18 18:08:35 +01:00
|
|
|
* byte order).
|
|
|
|
* Returns 0 if sucessful and -1 on failure
|
|
|
|
*/
|
2021-02-09 18:09:30 +01:00
|
|
|
static int parse_tcp_ts(struct tcphdr *tcph, void *data_end, __u32 *tsval,
|
|
|
|
__u32 *tsecr)
|
2021-01-07 18:30:53 +01:00
|
|
|
{
|
2021-01-27 12:16:11 +01:00
|
|
|
int len = tcph->doff << 2;
|
2021-01-26 18:34:23 +01:00
|
|
|
void *opt_end = (void *)tcph + len;
|
2021-01-27 12:16:11 +01:00
|
|
|
__u8 *pos = (__u8 *)(tcph + 1); //Current pos in TCP options
|
2021-03-29 20:13:33 +02:00
|
|
|
__u8 i, opt;
|
2021-04-15 14:13:54 +02:00
|
|
|
volatile __u8
|
|
|
|
opt_size; // Seems to ensure it's always read of from stack as u8
|
2021-01-07 18:30:53 +01:00
|
|
|
|
2021-01-27 12:16:11 +01:00
|
|
|
if (tcph + 1 > data_end || len <= sizeof(struct tcphdr))
|
|
|
|
return -1;
|
2021-03-15 18:23:23 +01:00
|
|
|
#pragma unroll //temporary solution until we can identify why the non-unrolled loop gets stuck in an infinite loop
|
2021-01-27 12:16:11 +01:00
|
|
|
for (i = 0; i < MAX_TCP_OPTIONS; i++) {
|
|
|
|
if (pos + 1 > opt_end || pos + 1 > data_end)
|
|
|
|
return -1;
|
2021-01-26 18:34:23 +01:00
|
|
|
|
2021-01-27 12:16:11 +01:00
|
|
|
opt = *pos;
|
|
|
|
if (opt == 0) // Reached end of TCP options
|
|
|
|
return -1;
|
2021-01-26 18:34:23 +01:00
|
|
|
|
2021-01-27 12:16:11 +01:00
|
|
|
if (opt == 1) { // TCP NOP option - advance one byte
|
|
|
|
pos++;
|
|
|
|
continue;
|
|
|
|
}
|
2021-01-26 18:34:23 +01:00
|
|
|
|
2021-01-27 12:16:11 +01:00
|
|
|
// Option > 1, should have option size
|
|
|
|
if (pos + 2 > opt_end || pos + 2 > data_end)
|
|
|
|
return -1;
|
|
|
|
opt_size = *(pos + 1);
|
2021-03-30 19:34:48 +02:00
|
|
|
if (opt_size < 2) // Stop parsing options if opt_size has an invalid value
|
|
|
|
return -1;
|
2021-01-26 18:34:23 +01:00
|
|
|
|
2021-01-27 12:16:11 +01:00
|
|
|
// Option-kind is TCP timestap (yey!)
|
|
|
|
if (opt == 8 && opt_size == 10) {
|
2021-03-29 20:13:33 +02:00
|
|
|
if (pos + 10 > opt_end || pos + 10 > data_end)
|
2021-01-27 12:16:11 +01:00
|
|
|
return -1;
|
pping: ensure TSval is monotonically increasing
The mechanism to ensure that only the first instance of each TSval is
timestamped is a simple equals check. This is check may fail if there
are reordered packets.
Consider a sequence of packets A, B, C and D, where A and B have
TSval=1 and C and D have TSval=2. If all packets arrive in
order (ABCD), then A and C will correctly be the only packets that are
timestamped (as B and D will have the same TSval as the previously
observed one). However, consider if B is reorderd so instead the
packets arrive as ACBD. In this scenario all ePPing will attempt to
timestamp all (instead of only A and C), as each packet now has a
different (but not always higher) TSval than the last seen
packet. Note that it will only sucessfully create the timestamps for
the later duplicated TSvals if the previous timestamp for the same
TSval has already been cleared out, so this is mainly an issue when
RTT < 1ms.
Fix this by only allowing a packet to be timestamped if its TSval is
stricly higher (accounting for wrap-around) than the last seen TSval,
and likewise only update last seen TSval if it is strictly higher than
the previous one.
To allow this calculation, also convert TSval and TSecr from network
byte order to host byte order when parsing the packet. While delaying
the transform from network to host byte order until the comparison
between the packet's TSval and last seen TSval could potentially save
the overhead of bpf_ntohs for some packets that do not need to go
through this check, most TCP packets will end up performing this
check, so performance difference should be minimal. Therefore, opt for
the simplier approach of converting TSval and TSecr directly, which
also makes them easier to interpret if ex. dumping the maps.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-08-31 17:03:24 +02:00
|
|
|
*tsval = bpf_ntohl(*(__u32 *)(pos + 2));
|
|
|
|
*tsecr = bpf_ntohl(*(__u32 *)(pos + 6));
|
2021-01-27 12:16:11 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2021-01-07 18:30:53 +01:00
|
|
|
|
2021-01-27 12:16:11 +01:00
|
|
|
// Some other TCP option - advance option-length bytes
|
|
|
|
pos += opt_size;
|
|
|
|
}
|
|
|
|
return -1;
|
2021-01-07 18:30:53 +01:00
|
|
|
}
|
2021-03-09 19:58:42 +01:00
|
|
|
|
2021-02-09 18:09:30 +01:00
|
|
|
/*
|
|
|
|
* Attempts to fetch an identifier for TCP packets, based on the TCP timestamp
|
2021-06-22 15:36:35 +02:00
|
|
|
* option.
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
*
|
|
|
|
* Will use the TSval as pid and TSecr as reply_pid, and the TCP source and dest
|
|
|
|
* as port numbers.
|
|
|
|
*
|
2022-03-22 13:24:09 +01:00
|
|
|
* If successful, tcph, sport, dport and proto_info will be set
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
* appropriately and 0 will be returned.
|
2022-03-22 13:24:09 +01:00
|
|
|
* On failure -1 will be returned (and arguments will not be set).
|
2021-02-09 18:09:30 +01:00
|
|
|
*/
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
static int parse_tcp_identifier(struct parsing_context *pctx,
|
2022-03-22 13:24:09 +01:00
|
|
|
struct tcphdr **tcph, __u16 *sport,
|
|
|
|
__u16 *dport, struct protocol_info *proto_info)
|
2021-02-09 18:09:30 +01:00
|
|
|
{
|
2022-03-22 13:24:09 +01:00
|
|
|
struct tcphdr *hdr;
|
|
|
|
if (parse_tcphdr(&pctx->nh, pctx->data_end, &hdr) < 0)
|
2021-02-12 18:31:30 +01:00
|
|
|
return -1;
|
|
|
|
|
2022-09-01 16:46:16 +02:00
|
|
|
if (config.skip_syn && hdr->syn)
|
|
|
|
return -1;
|
|
|
|
|
2022-03-22 13:24:09 +01:00
|
|
|
if (parse_tcp_ts(hdr, pctx->data_end, &proto_info->pid,
|
|
|
|
&proto_info->reply_pid) < 0)
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
return -1; //Possible TODO, fall back on seq/ack instead
|
|
|
|
|
|
|
|
// Do not timestamp pure ACKs (no payload)
|
2022-03-22 13:24:09 +01:00
|
|
|
proto_info->pid_valid =
|
|
|
|
pctx->nh.pos - pctx->data < pctx->pkt_len || hdr->syn;
|
2021-02-12 11:40:43 +01:00
|
|
|
|
2021-06-21 10:51:20 +02:00
|
|
|
// Do not match on non-ACKs (TSecr not valid)
|
2022-03-22 13:24:09 +01:00
|
|
|
proto_info->reply_pid_valid = hdr->ack;
|
2021-06-21 10:51:20 +02:00
|
|
|
|
2021-06-22 15:36:35 +02:00
|
|
|
// Check if connection is opening/closing
|
2022-03-22 13:24:09 +01:00
|
|
|
if (hdr->rst) {
|
|
|
|
proto_info->event_type = FLOW_EVENT_CLOSING_BOTH;
|
|
|
|
proto_info->event_reason = EVENT_REASON_RST;
|
|
|
|
} else if (hdr->fin) {
|
|
|
|
proto_info->event_type = FLOW_EVENT_CLOSING;
|
|
|
|
proto_info->event_reason = EVENT_REASON_FIN;
|
|
|
|
} else if (hdr->syn) {
|
|
|
|
proto_info->event_type = FLOW_EVENT_OPENING;
|
|
|
|
proto_info->event_reason =
|
|
|
|
hdr->ack ? EVENT_REASON_SYN_ACK : EVENT_REASON_SYN;
|
2022-11-04 13:41:47 +01:00
|
|
|
proto_info->wait_first_edge = false;
|
2021-06-22 15:36:35 +02:00
|
|
|
} else {
|
2022-03-22 13:24:09 +01:00
|
|
|
proto_info->event_type = FLOW_EVENT_NONE;
|
|
|
|
proto_info->event_reason = EVENT_REASON_NONE;
|
2022-11-04 13:41:47 +01:00
|
|
|
proto_info->wait_first_edge = true;
|
2021-06-22 15:36:35 +02:00
|
|
|
}
|
|
|
|
|
2022-03-22 13:24:09 +01:00
|
|
|
*sport = hdr->source;
|
|
|
|
*dport = hdr->dest;
|
|
|
|
*tcph = hdr;
|
|
|
|
|
2021-02-09 18:09:30 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-12-08 10:13:50 +01:00
|
|
|
/*
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
* Attempts to fetch an identifier for an ICMPv6 header, based on the echo
|
2021-12-08 10:13:50 +01:00
|
|
|
* request/reply sequence number.
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
*
|
|
|
|
* Will use the echo sequence number as pid/reply_pid and the echo identifier
|
2022-03-22 13:24:09 +01:00
|
|
|
* as both src and dst port numbers. Echo requests will only generate a valid
|
|
|
|
* pid and echo replies will only generate a valid reply_pid.
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
*
|
2022-03-22 13:24:09 +01:00
|
|
|
* If successful, icmp6h, sport, dport and proto_info will be set appropriately
|
|
|
|
* and 0 will be returned.
|
|
|
|
* On failure, -1 will be returned (and arguments will not be set).
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
*
|
|
|
|
* Note: Will store the 16-bit sequence number in network byte order
|
2022-03-22 13:24:09 +01:00
|
|
|
* in the 32-bit proto_info->(reply_)pid.
|
2021-12-08 10:13:50 +01:00
|
|
|
*/
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
static int parse_icmp6_identifier(struct parsing_context *pctx,
|
2022-03-22 13:24:09 +01:00
|
|
|
struct icmp6hdr **icmp6h, __u16 *sport,
|
|
|
|
__u16 *dport,
|
|
|
|
struct protocol_info *proto_info)
|
2021-12-08 10:13:50 +01:00
|
|
|
{
|
2022-03-22 13:24:09 +01:00
|
|
|
struct icmp6hdr *hdr;
|
|
|
|
if (parse_icmp6hdr(&pctx->nh, pctx->data_end, &hdr) < 0)
|
2021-12-08 10:13:50 +01:00
|
|
|
return -1;
|
|
|
|
|
2022-03-22 13:24:09 +01:00
|
|
|
if (hdr->icmp6_code != 0)
|
2021-12-08 10:13:50 +01:00
|
|
|
return -1;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
|
2022-03-22 13:24:09 +01:00
|
|
|
if (hdr->icmp6_type == ICMPV6_ECHO_REQUEST) {
|
|
|
|
proto_info->pid = hdr->icmp6_sequence;
|
|
|
|
proto_info->pid_valid = true;
|
|
|
|
proto_info->reply_pid = 0;
|
|
|
|
proto_info->reply_pid_valid = false;
|
|
|
|
} else if (hdr->icmp6_type == ICMPV6_ECHO_REPLY) {
|
|
|
|
proto_info->reply_pid = hdr->icmp6_sequence;
|
|
|
|
proto_info->reply_pid_valid = true;
|
|
|
|
proto_info->pid = 0;
|
|
|
|
proto_info->pid_valid = false;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
} else {
|
2021-12-08 10:13:50 +01:00
|
|
|
return -1;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
}
|
2021-12-08 10:13:50 +01:00
|
|
|
|
2022-03-22 13:24:09 +01:00
|
|
|
proto_info->event_type = FLOW_EVENT_NONE;
|
|
|
|
proto_info->event_reason = EVENT_REASON_NONE;
|
2022-11-04 13:41:47 +01:00
|
|
|
proto_info->wait_first_edge = false;
|
2022-03-22 13:24:09 +01:00
|
|
|
*sport = hdr->icmp6_identifier;
|
|
|
|
*dport = hdr->icmp6_identifier;
|
|
|
|
*icmp6h = hdr;
|
|
|
|
|
2021-12-08 10:13:50 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Same as parse_icmp6_identifier, but for an ICMP(v4) header instead.
|
|
|
|
*/
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
static int parse_icmp_identifier(struct parsing_context *pctx,
|
2022-03-22 13:24:09 +01:00
|
|
|
struct icmphdr **icmph, __u16 *sport,
|
|
|
|
__u16 *dport, struct protocol_info *proto_info)
|
2021-12-08 10:13:50 +01:00
|
|
|
{
|
2022-03-22 13:24:09 +01:00
|
|
|
struct icmphdr *hdr;
|
|
|
|
if (parse_icmphdr(&pctx->nh, pctx->data_end, &hdr) < 0)
|
2021-12-08 10:13:50 +01:00
|
|
|
return -1;
|
|
|
|
|
2022-03-22 13:24:09 +01:00
|
|
|
if (hdr->code != 0)
|
2021-12-08 10:13:50 +01:00
|
|
|
return -1;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
|
2022-03-22 13:24:09 +01:00
|
|
|
if (hdr->type == ICMP_ECHO) {
|
|
|
|
proto_info->pid = hdr->un.echo.sequence;
|
|
|
|
proto_info->pid_valid = true;
|
|
|
|
proto_info->reply_pid = 0;
|
|
|
|
proto_info->reply_pid_valid = false;
|
|
|
|
} else if (hdr->type == ICMP_ECHOREPLY) {
|
|
|
|
proto_info->reply_pid = hdr->un.echo.sequence;
|
|
|
|
proto_info->reply_pid_valid = true;
|
|
|
|
proto_info->pid = 0;
|
|
|
|
proto_info->pid_valid = false;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
} else {
|
2021-12-08 10:13:50 +01:00
|
|
|
return -1;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
}
|
2021-12-08 10:13:50 +01:00
|
|
|
|
2022-03-22 13:24:09 +01:00
|
|
|
proto_info->event_type = FLOW_EVENT_NONE;
|
|
|
|
proto_info->event_reason = EVENT_REASON_NONE;
|
2022-11-04 13:41:47 +01:00
|
|
|
proto_info->wait_first_edge = false;
|
2022-03-22 13:24:09 +01:00
|
|
|
*sport = hdr->un.echo.id;
|
|
|
|
*dport = hdr->un.echo.id;
|
|
|
|
*icmph = hdr;
|
|
|
|
|
2021-12-08 10:13:50 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-02-09 18:09:30 +01:00
|
|
|
/*
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
* Attempts to parse the packet defined by pctx for a valid packet identifier
|
|
|
|
* and reply identifier, filling in p_info.
|
|
|
|
*
|
|
|
|
* If succesful, all members of p_info will be set appropriately and 0 will
|
|
|
|
* be returned.
|
|
|
|
* On failure -1 will be returned (no garantuees on p_info members).
|
2021-02-09 18:09:30 +01:00
|
|
|
*/
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
static int parse_packet_identifier(struct parsing_context *pctx,
|
|
|
|
struct packet_info *p_info)
|
2021-02-09 18:09:30 +01:00
|
|
|
{
|
2021-02-12 11:40:43 +01:00
|
|
|
int proto, err;
|
2021-02-09 18:09:30 +01:00
|
|
|
struct ethhdr *eth;
|
2022-03-22 13:24:09 +01:00
|
|
|
struct protocol_info proto_info;
|
2022-06-21 17:33:58 +02:00
|
|
|
union {
|
|
|
|
struct iphdr *iph;
|
|
|
|
struct ipv6hdr *ip6h;
|
|
|
|
} iph_ptr;
|
|
|
|
union {
|
|
|
|
struct tcphdr *tcph;
|
|
|
|
struct icmphdr *icmph;
|
|
|
|
struct icmp6hdr *icmp6h;
|
|
|
|
} transporth_ptr;
|
2021-02-09 18:09:30 +01:00
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
p_info->time = bpf_ktime_get_ns();
|
2023-04-05 16:35:03 +02:00
|
|
|
p_info->pkt_len = pctx->pkt_len;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
proto = parse_ethhdr(&pctx->nh, pctx->data_end, ð);
|
2021-02-09 18:09:30 +01:00
|
|
|
|
|
|
|
// Parse IPv4/6 header
|
|
|
|
if (proto == bpf_htons(ETH_P_IP)) {
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
p_info->pid.flow.ipv = AF_INET;
|
|
|
|
p_info->pid.flow.proto =
|
2022-06-21 17:33:58 +02:00
|
|
|
parse_iphdr(&pctx->nh, pctx->data_end, &iph_ptr.iph);
|
2021-02-09 18:09:30 +01:00
|
|
|
} else if (proto == bpf_htons(ETH_P_IPV6)) {
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
p_info->pid.flow.ipv = AF_INET6;
|
|
|
|
p_info->pid.flow.proto =
|
2022-06-21 17:33:58 +02:00
|
|
|
parse_ip6hdr(&pctx->nh, pctx->data_end, &iph_ptr.ip6h);
|
2021-02-12 11:40:43 +01:00
|
|
|
} else {
|
2021-02-09 18:09:30 +01:00
|
|
|
return -1;
|
2021-02-12 11:40:43 +01:00
|
|
|
}
|
2021-02-09 18:09:30 +01:00
|
|
|
|
2021-12-08 10:13:50 +01:00
|
|
|
// Parse identifer from suitable protocol
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
if (config.track_tcp && p_info->pid.flow.proto == IPPROTO_TCP)
|
2022-06-21 17:33:58 +02:00
|
|
|
err = parse_tcp_identifier(pctx, &transporth_ptr.tcph,
|
2022-03-22 13:24:09 +01:00
|
|
|
&p_info->pid.flow.saddr.port,
|
|
|
|
&p_info->pid.flow.daddr.port,
|
|
|
|
&proto_info);
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
else if (config.track_icmp &&
|
|
|
|
p_info->pid.flow.proto == IPPROTO_ICMPV6 &&
|
|
|
|
p_info->pid.flow.ipv == AF_INET6)
|
2022-06-21 17:33:58 +02:00
|
|
|
err = parse_icmp6_identifier(pctx, &transporth_ptr.icmp6h,
|
2022-03-22 13:24:09 +01:00
|
|
|
&p_info->pid.flow.saddr.port,
|
|
|
|
&p_info->pid.flow.daddr.port,
|
|
|
|
&proto_info);
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
else if (config.track_icmp && p_info->pid.flow.proto == IPPROTO_ICMP &&
|
|
|
|
p_info->pid.flow.ipv == AF_INET)
|
2022-06-21 17:33:58 +02:00
|
|
|
err = parse_icmp_identifier(pctx, &transporth_ptr.icmph,
|
2022-03-22 13:24:09 +01:00
|
|
|
&p_info->pid.flow.saddr.port,
|
|
|
|
&p_info->pid.flow.daddr.port,
|
|
|
|
&proto_info);
|
2021-12-08 10:13:50 +01:00
|
|
|
else
|
|
|
|
return -1; // No matching protocol
|
|
|
|
if (err)
|
|
|
|
return -1; // Failed parsing protocol
|
2021-02-09 18:09:30 +01:00
|
|
|
|
2022-03-22 13:24:09 +01:00
|
|
|
// Sucessfully parsed packet identifier - fill in remaining members and return
|
|
|
|
p_info->pid.identifier = proto_info.pid;
|
|
|
|
p_info->pid_valid = proto_info.pid_valid;
|
|
|
|
p_info->reply_pid.identifier = proto_info.reply_pid;
|
|
|
|
p_info->reply_pid_valid = proto_info.reply_pid_valid;
|
|
|
|
p_info->event_type = proto_info.event_type;
|
|
|
|
p_info->event_reason = proto_info.event_reason;
|
2022-11-04 13:41:47 +01:00
|
|
|
p_info->wait_first_edge = proto_info.wait_first_edge;
|
2022-03-22 13:24:09 +01:00
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
if (p_info->pid.flow.ipv == AF_INET) {
|
|
|
|
map_ipv4_to_ipv6(&p_info->pid.flow.saddr.ip,
|
2022-06-21 17:33:58 +02:00
|
|
|
iph_ptr.iph->saddr);
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
map_ipv4_to_ipv6(&p_info->pid.flow.daddr.ip,
|
2022-06-21 17:33:58 +02:00
|
|
|
iph_ptr.iph->daddr);
|
|
|
|
p_info->ip_len = bpf_ntohs(iph_ptr.iph->tot_len);
|
|
|
|
p_info->ip_tos.ipv4_tos = iph_ptr.iph->tos;
|
2021-02-09 18:09:30 +01:00
|
|
|
} else { // IPv6
|
2022-06-21 17:33:58 +02:00
|
|
|
p_info->pid.flow.saddr.ip = iph_ptr.ip6h->saddr;
|
|
|
|
p_info->pid.flow.daddr.ip = iph_ptr.ip6h->daddr;
|
|
|
|
p_info->ip_len = bpf_ntohs(iph_ptr.ip6h->payload_len);
|
|
|
|
p_info->ip_tos.ipv6_tos =
|
|
|
|
*(__be32 *)iph_ptr.ip6h & IPV6_FLOWINFO_MASK;
|
2021-02-09 18:09:30 +01:00
|
|
|
}
|
2021-01-07 18:30:53 +01:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
p_info->pid_flow_is_dfkey = is_dualflow_key(&p_info->pid.flow);
|
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
reverse_flow(&p_info->reply_pid.flow, &p_info->pid.flow);
|
|
|
|
p_info->payload = remaining_pkt_payload(pctx);
|
|
|
|
|
|
|
|
return 0;
|
2021-05-07 14:54:12 +02:00
|
|
|
}
|
|
|
|
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
/*
|
|
|
|
* Global versions of parse_packet_identifer that should allow for
|
|
|
|
* function-by-function verification, and reduce the overall complexity.
|
|
|
|
* Need separate versions for tc and XDP so that verifier understands that the
|
|
|
|
* first argument is PTR_TO_CTX, and therefore their data and data_end pointers
|
|
|
|
* are valid packet pointers.
|
|
|
|
*/
|
|
|
|
__noinline int parse_packet_identifer_tc(struct __sk_buff *ctx,
|
|
|
|
struct packet_info *p_info)
|
|
|
|
{
|
|
|
|
if (!p_info)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
struct parsing_context pctx = {
|
|
|
|
.data = (void *)(long)ctx->data,
|
|
|
|
.data_end = (void *)(long)ctx->data_end,
|
|
|
|
.nh = { .pos = pctx.data },
|
|
|
|
.pkt_len = ctx->len,
|
|
|
|
};
|
|
|
|
|
|
|
|
return parse_packet_identifier(&pctx, p_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
__noinline int parse_packet_identifer_xdp(struct xdp_md *ctx,
|
|
|
|
struct packet_info *p_info)
|
|
|
|
{
|
|
|
|
if (!p_info)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
struct parsing_context pctx = {
|
|
|
|
.data = (void *)(long)ctx->data,
|
|
|
|
.data_end = (void *)(long)ctx->data_end,
|
|
|
|
.nh = { .pos = pctx.data },
|
|
|
|
.pkt_len = pctx.data_end - pctx.data,
|
|
|
|
};
|
|
|
|
|
|
|
|
return parse_packet_identifier(&pctx, p_info);
|
|
|
|
}
|
|
|
|
|
2022-02-10 16:11:21 +01:00
|
|
|
/*
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
* Calculate a smoothed rtt similar to how TCP stack does it in
|
2022-02-10 16:11:21 +01:00
|
|
|
* net/ipv4/tcp_input.c/tcp_rtt_estimator().
|
|
|
|
*
|
|
|
|
* NOTE: Will cause roundoff errors, but if RTTs > 1000ns errors should be small
|
|
|
|
*/
|
|
|
|
static __u64 calculate_srtt(__u64 prev_srtt, __u64 rtt)
|
|
|
|
{
|
|
|
|
if (!prev_srtt)
|
|
|
|
return rtt;
|
|
|
|
// srtt = 7/8*prev_srtt + 1/8*rtt
|
|
|
|
return prev_srtt - (prev_srtt >> 3) + (rtt >> 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool is_rate_limited(__u64 now, __u64 last_ts, __u64 rtt)
|
|
|
|
{
|
|
|
|
if (now < last_ts)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// RTT-based rate limit
|
|
|
|
if (config.rtt_rate && rtt)
|
|
|
|
return now - last_ts < FIXPOINT_TO_UINT(config.rtt_rate * rtt);
|
|
|
|
|
|
|
|
// Static rate limit
|
|
|
|
return now - last_ts < config.rate_limit;
|
|
|
|
}
|
|
|
|
|
2022-02-03 12:03:22 +01:00
|
|
|
/*
|
|
|
|
* Send a flow opening event through the perf-buffer.
|
|
|
|
* As these events are only sent upon receiving a reply, need to access state
|
|
|
|
* of the reverse flow to get reason flow was opened and when the original
|
|
|
|
* packet opening the flow was sent.
|
|
|
|
*/
|
|
|
|
static void send_flow_open_event(void *ctx, struct packet_info *p_info,
|
|
|
|
struct flow_state *rev_flow)
|
|
|
|
{
|
2023-07-04 17:34:41 +02:00
|
|
|
if (!config.push_individual_events)
|
|
|
|
return;
|
|
|
|
|
2022-02-03 12:03:22 +01:00
|
|
|
struct flow_event fe = {
|
|
|
|
.event_type = EVENT_TYPE_FLOW,
|
|
|
|
.flow_event_type = FLOW_EVENT_OPENING,
|
|
|
|
.source = EVENT_SOURCE_PKT_DEST,
|
|
|
|
.flow = p_info->pid.flow,
|
|
|
|
.reason = rev_flow->opening_reason,
|
|
|
|
.timestamp = rev_flow->last_timestamp,
|
|
|
|
.reserved = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &fe, sizeof(fe));
|
|
|
|
}
|
|
|
|
|
2021-06-22 15:22:11 +02:00
|
|
|
/*
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
* Sends a flow-event message based on p_info.
|
|
|
|
*
|
|
|
|
* The rev_flow argument is used to inform if the message is for the flow
|
|
|
|
* in the current direction or the reverse flow, and will adapt the flow and
|
|
|
|
* source members accordingly.
|
2021-06-22 15:22:11 +02:00
|
|
|
*/
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
static void send_flow_event(void *ctx, struct packet_info *p_info,
|
|
|
|
bool rev_flow)
|
2021-06-22 15:22:11 +02:00
|
|
|
{
|
2023-07-04 17:34:41 +02:00
|
|
|
if (!config.push_individual_events)
|
|
|
|
return;
|
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
struct flow_event fe = {
|
|
|
|
.event_type = EVENT_TYPE_FLOW,
|
|
|
|
.flow_event_type = p_info->event_type,
|
|
|
|
.reason = p_info->event_reason,
|
|
|
|
.timestamp = p_info->time,
|
|
|
|
.reserved = 0, // Make sure it's initilized
|
|
|
|
};
|
|
|
|
|
|
|
|
if (rev_flow) {
|
|
|
|
fe.flow = p_info->pid.flow;
|
|
|
|
fe.source = EVENT_SOURCE_PKT_SRC;
|
|
|
|
} else {
|
|
|
|
fe.flow = p_info->reply_pid.flow;
|
|
|
|
fe.source = EVENT_SOURCE_PKT_DEST;
|
|
|
|
}
|
|
|
|
|
|
|
|
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &fe, sizeof(fe));
|
2021-06-22 15:22:11 +02:00
|
|
|
}
|
|
|
|
|
2022-02-03 15:51:22 +01:00
|
|
|
/*
|
|
|
|
* Send a map-full event for the map.
|
|
|
|
* Will only trigger once every WARN_MAP_FULL_INTERVAL
|
|
|
|
*/
|
|
|
|
static void send_map_full_event(void *ctx, struct packet_info *p_info,
|
|
|
|
enum pping_map map)
|
|
|
|
{
|
|
|
|
struct map_full_event me;
|
|
|
|
|
|
|
|
if (p_info->time < last_warn_time[map] ||
|
|
|
|
p_info->time - last_warn_time[map] < WARN_MAP_FULL_INTERVAL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
last_warn_time[map] = p_info->time;
|
|
|
|
|
|
|
|
__builtin_memset(&me, 0, sizeof(me));
|
|
|
|
me.event_type = EVENT_TYPE_MAP_FULL;
|
|
|
|
me.timestamp = p_info->time;
|
|
|
|
me.flow = p_info->pid.flow;
|
|
|
|
me.map = map;
|
|
|
|
|
|
|
|
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &me, sizeof(me));
|
|
|
|
}
|
|
|
|
|
2022-09-27 13:46:34 +02:00
|
|
|
static void send_rtt_event(void *ctx, __u64 rtt, struct flow_state *f_state,
|
2023-07-04 17:34:41 +02:00
|
|
|
struct packet_info *p_info)
|
2022-09-27 13:46:34 +02:00
|
|
|
{
|
2023-07-04 17:34:41 +02:00
|
|
|
if (!config.push_individual_events)
|
|
|
|
return;
|
|
|
|
|
2022-09-27 13:46:34 +02:00
|
|
|
struct rtt_event re = {
|
|
|
|
.event_type = EVENT_TYPE_RTT,
|
|
|
|
.timestamp = p_info->time,
|
|
|
|
.flow = p_info->pid.flow,
|
|
|
|
.padding = 0,
|
|
|
|
.rtt = rtt,
|
|
|
|
.min_rtt = f_state->min_rtt,
|
|
|
|
.sent_pkts = f_state->sent_pkts,
|
|
|
|
.sent_bytes = f_state->sent_bytes,
|
|
|
|
.rec_pkts = f_state->rec_pkts,
|
|
|
|
.rec_bytes = f_state->rec_bytes,
|
|
|
|
.match_on_egress = !p_info->is_ingress,
|
|
|
|
.reserved = { 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &re, sizeof(re));
|
|
|
|
}
|
|
|
|
|
2021-12-08 10:06:30 +01:00
|
|
|
/*
|
2022-03-22 17:59:18 +01:00
|
|
|
* Initilizes an "empty" flow state based on the forward direction of the
|
|
|
|
* current packet
|
|
|
|
*/
|
|
|
|
static void init_flowstate(struct flow_state *f_state,
|
|
|
|
struct packet_info *p_info)
|
|
|
|
{
|
2022-03-30 17:40:54 +02:00
|
|
|
f_state->conn_state = CONNECTION_STATE_WAITOPEN;
|
2022-03-22 17:59:18 +01:00
|
|
|
f_state->last_timestamp = p_info->time;
|
2022-11-04 13:41:47 +01:00
|
|
|
/* We should only ever create new flows for packet with valid pid,
|
|
|
|
so assume pid is valid*/
|
|
|
|
f_state->last_id = p_info->pid.identifier;
|
2022-03-22 17:59:18 +01:00
|
|
|
f_state->opening_reason = p_info->event_type == FLOW_EVENT_OPENING ?
|
|
|
|
p_info->event_reason :
|
|
|
|
EVENT_REASON_FIRST_OBS_PCKT;
|
2022-11-04 13:41:47 +01:00
|
|
|
f_state->has_been_timestamped = false;
|
2022-03-22 17:59:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void init_empty_flowstate(struct flow_state *f_state)
|
|
|
|
{
|
2022-03-30 17:40:54 +02:00
|
|
|
f_state->conn_state = CONNECTION_STATE_EMPTY;
|
2022-11-04 13:41:47 +01:00
|
|
|
f_state->has_been_timestamped = false;
|
2022-03-22 17:59:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initilize a new (assumed 0-initlized) dual flow state based on the current
|
|
|
|
* packet.
|
2021-12-08 10:06:30 +01:00
|
|
|
*/
|
2022-03-22 17:59:18 +01:00
|
|
|
static void init_dualflow_state(struct dual_flow_state *df_state,
|
|
|
|
struct packet_info *p_info)
|
|
|
|
{
|
|
|
|
struct flow_state *fw_state =
|
|
|
|
get_flowstate_from_packet(df_state, p_info);
|
|
|
|
struct flow_state *rev_state =
|
|
|
|
get_reverse_flowstate_from_packet(df_state, p_info);
|
|
|
|
|
|
|
|
init_flowstate(fw_state, p_info);
|
|
|
|
init_empty_flowstate(rev_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct dual_flow_state *
|
2022-11-04 13:41:47 +01:00
|
|
|
create_dualflow_state(void *ctx, struct packet_info *p_info)
|
2021-04-15 14:13:54 +02:00
|
|
|
{
|
2022-03-22 17:59:18 +01:00
|
|
|
struct network_tuple *key = get_dualflow_key_from_packet(p_info);
|
|
|
|
struct dual_flow_state new_state = { 0 };
|
2021-04-15 14:13:54 +02:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
init_dualflow_state(&new_state, p_info);
|
2022-02-03 12:03:22 +01:00
|
|
|
|
2022-11-04 13:41:47 +01:00
|
|
|
if (bpf_map_update_elem(&flow_state, key, &new_state, BPF_NOEXIST) !=
|
2022-03-22 17:59:18 +01:00
|
|
|
0) {
|
2022-02-03 15:51:22 +01:00
|
|
|
send_map_full_event(ctx, p_info, PPING_MAP_FLOWSTATE);
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
return NULL;
|
2022-02-03 15:51:22 +01:00
|
|
|
}
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
return bpf_map_lookup_elem(&flow_state, key);
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
}
|
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
static struct dual_flow_state *
|
2022-11-04 13:41:47 +01:00
|
|
|
lookup_or_create_dualflow_state(void *ctx, struct packet_info *p_info)
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
{
|
2022-03-22 17:59:18 +01:00
|
|
|
struct dual_flow_state *df_state;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
df_state = bpf_map_lookup_elem(&flow_state,
|
|
|
|
get_dualflow_key_from_packet(p_info));
|
2022-02-03 12:03:22 +01:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
if (df_state)
|
|
|
|
return df_state;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
// Only try to create new state if we have a valid pid
|
|
|
|
if (!p_info->pid_valid || p_info->event_type == FLOW_EVENT_CLOSING ||
|
|
|
|
p_info->event_type == FLOW_EVENT_CLOSING_BOTH)
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
return NULL;
|
2021-04-15 14:13:54 +02:00
|
|
|
|
2022-11-04 13:41:47 +01:00
|
|
|
return create_dualflow_state(ctx, p_info);
|
2022-03-22 17:59:18 +01:00
|
|
|
}
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
static bool is_flowstate_active(struct flow_state *f_state)
|
|
|
|
{
|
2022-03-30 17:40:54 +02:00
|
|
|
return f_state->conn_state != CONNECTION_STATE_EMPTY &&
|
|
|
|
f_state->conn_state != CONNECTION_STATE_CLOSED;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
}
|
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
static void update_forward_flowstate(struct packet_info *p_info,
|
2022-11-04 13:41:47 +01:00
|
|
|
struct flow_state *f_state)
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
{
|
2022-03-22 17:59:18 +01:00
|
|
|
// "Create" flowstate if it's empty
|
2022-11-04 13:41:47 +01:00
|
|
|
if (f_state->conn_state == CONNECTION_STATE_EMPTY && p_info->pid_valid)
|
2022-03-22 17:59:18 +01:00
|
|
|
init_flowstate(f_state, p_info);
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
if (is_flowstate_active(f_state)) {
|
|
|
|
f_state->sent_pkts++;
|
|
|
|
f_state->sent_bytes += p_info->payload;
|
|
|
|
}
|
|
|
|
}
|
2021-06-22 15:22:11 +02:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
static void update_reverse_flowstate(void *ctx, struct packet_info *p_info,
|
|
|
|
struct flow_state *f_state)
|
|
|
|
{
|
|
|
|
if (!is_flowstate_active(f_state))
|
|
|
|
return;
|
|
|
|
|
|
|
|
// First time we see reply for flow?
|
2022-03-30 17:40:54 +02:00
|
|
|
if (f_state->conn_state == CONNECTION_STATE_WAITOPEN &&
|
2022-02-03 12:03:22 +01:00
|
|
|
p_info->event_type != FLOW_EVENT_CLOSING_BOTH) {
|
2022-03-30 17:40:54 +02:00
|
|
|
f_state->conn_state = CONNECTION_STATE_OPEN;
|
2022-02-03 12:03:22 +01:00
|
|
|
send_flow_open_event(ctx, p_info, f_state);
|
|
|
|
}
|
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
f_state->rec_pkts++;
|
|
|
|
f_state->rec_bytes += p_info->payload;
|
2022-03-22 17:59:18 +01:00
|
|
|
}
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
static bool should_notify_closing(struct flow_state *f_state)
|
|
|
|
{
|
2022-03-30 17:40:54 +02:00
|
|
|
return f_state->conn_state == CONNECTION_STATE_OPEN;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
}
|
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
static void close_and_delete_flows(void *ctx, struct packet_info *p_info,
|
|
|
|
struct flow_state *fw_flow,
|
|
|
|
struct flow_state *rev_flow)
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
{
|
2022-03-22 17:59:18 +01:00
|
|
|
// Forward flow closing
|
|
|
|
if (p_info->event_type == FLOW_EVENT_CLOSING ||
|
|
|
|
p_info->event_type == FLOW_EVENT_CLOSING_BOTH) {
|
|
|
|
if (should_notify_closing(fw_flow))
|
|
|
|
send_flow_event(ctx, p_info, false);
|
2022-03-30 17:40:54 +02:00
|
|
|
fw_flow->conn_state = CONNECTION_STATE_CLOSED;
|
2022-03-22 17:59:18 +01:00
|
|
|
}
|
2022-02-03 12:03:22 +01:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
// Reverse flow closing
|
|
|
|
if (p_info->event_type == FLOW_EVENT_CLOSING_BOTH) {
|
|
|
|
if (should_notify_closing(rev_flow))
|
|
|
|
send_flow_event(ctx, p_info, true);
|
2022-03-30 17:40:54 +02:00
|
|
|
rev_flow->conn_state = CONNECTION_STATE_CLOSED;
|
2021-04-15 14:13:54 +02:00
|
|
|
}
|
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
// Delete flowstate entry if neither flow is open anymore
|
|
|
|
if (!is_flowstate_active(fw_flow) && !is_flowstate_active(rev_flow)) {
|
|
|
|
if (bpf_map_delete_elem(&flow_state,
|
|
|
|
get_dualflow_key_from_packet(p_info)) ==
|
|
|
|
0)
|
2022-02-17 14:01:08 +01:00
|
|
|
debug_increment_autodel(PPING_MAP_FLOWSTATE);
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
}
|
|
|
|
}
|
2021-06-22 15:22:11 +02:00
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
/*
|
|
|
|
* Return true if p_info->pid.flow.daddr is a "local" address.
|
|
|
|
*
|
|
|
|
* Works by performing a fib lookup for p_info->pid.flow.
|
|
|
|
* Lookup struct filled based on examples from
|
|
|
|
* samples/bpf/xdp_fwd_kern.c/xdp_fwd_flags() and
|
|
|
|
* tools/testing/selftests/bpf/progs/test_tc_neigh_fib.c
|
|
|
|
*/
|
2022-05-31 21:19:19 +02:00
|
|
|
static bool is_local_address(struct packet_info *p_info, void *ctx)
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct bpf_fib_lookup lookup;
|
|
|
|
__builtin_memset(&lookup, 0, sizeof(lookup));
|
|
|
|
|
2022-05-31 21:19:19 +02:00
|
|
|
lookup.ifindex = p_info->ingress_ifindex;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
lookup.family = p_info->pid.flow.ipv;
|
2022-06-21 17:33:58 +02:00
|
|
|
lookup.tot_len = p_info->ip_len;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
|
|
|
|
if (lookup.family == AF_INET) {
|
2022-06-21 17:33:58 +02:00
|
|
|
lookup.tos = p_info->ip_tos.ipv4_tos;
|
|
|
|
lookup.ipv4_src = ipv4_from_ipv6(&p_info->pid.flow.saddr.ip);
|
|
|
|
lookup.ipv4_dst = ipv4_from_ipv6(&p_info->pid.flow.daddr.ip);
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
} else if (lookup.family == AF_INET6) {
|
|
|
|
struct in6_addr *src = (struct in6_addr *)lookup.ipv6_src;
|
|
|
|
struct in6_addr *dst = (struct in6_addr *)lookup.ipv6_dst;
|
|
|
|
|
2022-06-21 17:33:58 +02:00
|
|
|
lookup.flowinfo = p_info->ip_tos.ipv6_tos;
|
|
|
|
*src = p_info->pid.flow.saddr.ip;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
*dst = p_info->pid.flow.daddr.ip;
|
2021-04-15 14:13:54 +02:00
|
|
|
}
|
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
lookup.l4_protocol = p_info->pid.flow.proto;
|
|
|
|
lookup.sport = 0;
|
|
|
|
lookup.dport = 0;
|
|
|
|
|
|
|
|
ret = bpf_fib_lookup(ctx, &lookup, sizeof(lookup), 0);
|
|
|
|
|
|
|
|
return ret == BPF_FIB_LKUP_RET_NOT_FWDED ||
|
|
|
|
ret == BPF_FIB_LKUP_RET_FWD_DISABLED;
|
|
|
|
}
|
|
|
|
|
pping: ensure TSval is monotonically increasing
The mechanism to ensure that only the first instance of each TSval is
timestamped is a simple equals check. This is check may fail if there
are reordered packets.
Consider a sequence of packets A, B, C and D, where A and B have
TSval=1 and C and D have TSval=2. If all packets arrive in
order (ABCD), then A and C will correctly be the only packets that are
timestamped (as B and D will have the same TSval as the previously
observed one). However, consider if B is reorderd so instead the
packets arrive as ACBD. In this scenario all ePPing will attempt to
timestamp all (instead of only A and C), as each packet now has a
different (but not always higher) TSval than the last seen
packet. Note that it will only sucessfully create the timestamps for
the later duplicated TSvals if the previous timestamp for the same
TSval has already been cleared out, so this is mainly an issue when
RTT < 1ms.
Fix this by only allowing a packet to be timestamped if its TSval is
stricly higher (accounting for wrap-around) than the last seen TSval,
and likewise only update last seen TSval if it is strictly higher than
the previous one.
To allow this calculation, also convert TSval and TSecr from network
byte order to host byte order when parsing the packet. While delaying
the transform from network to host byte order until the comparison
between the packet's TSval and last seen TSval could potentially save
the overhead of bpf_ntohs for some packets that do not need to go
through this check, most TCP packets will end up performing this
check, so performance difference should be minimal. Therefore, opt for
the simplier approach of converting TSval and TSecr directly, which
also makes them easier to interpret if ex. dumping the maps.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-08-31 17:03:24 +02:00
|
|
|
static bool is_new_identifier(struct packet_id *pid, struct flow_state *f_state)
|
|
|
|
{
|
|
|
|
if (pid->flow.proto == IPPROTO_TCP)
|
|
|
|
/* TCP timestamps should be monotonically non-decreasing
|
|
|
|
* Check that pid > last_ts (considering wrap around) by
|
|
|
|
* checking 0 < pid - last_ts < 2^31 as specified by
|
|
|
|
* RFC7323 Section 5.2*/
|
|
|
|
return pid->identifier - f_state->last_id > 0 &&
|
|
|
|
pid->identifier - f_state->last_id < 1UL << 31;
|
|
|
|
|
|
|
|
return pid->identifier != f_state->last_id;
|
|
|
|
}
|
|
|
|
|
2023-07-04 17:34:41 +02:00
|
|
|
static void create_ipprefix_key_v4(__u32 *prefix_key, struct in6_addr *ip)
|
|
|
|
{
|
|
|
|
*prefix_key = ip->s6_addr32[3] & config.ipv4_prefix_mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void create_ipprefix_key_v6(__u64 *prefix_key, struct in6_addr *ip)
|
|
|
|
{
|
|
|
|
*prefix_key = *(__u64 *)&ip->in6_u & config.ipv6_prefix_mask;
|
|
|
|
// *prefix_key = *(__u64 *)ip & config.ipv6_prefix_mask; // gives verifier rejection "misaligned stack access off"
|
|
|
|
}
|
|
|
|
|
2023-10-17 16:23:51 +02:00
|
|
|
static struct aggregated_stats *
|
2023-07-04 17:34:41 +02:00
|
|
|
lookup_or_create_aggregation_stats(struct in6_addr *ip, __u8 ipv)
|
|
|
|
{
|
2023-10-17 16:23:51 +02:00
|
|
|
struct aggregated_stats *agg;
|
2023-07-04 17:34:41 +02:00
|
|
|
struct ipprefix_key key;
|
2023-07-04 19:53:26 +02:00
|
|
|
__u32 *map_choice;
|
|
|
|
__u32 zero = 0;
|
2023-07-04 17:34:41 +02:00
|
|
|
void *agg_map;
|
|
|
|
int err;
|
|
|
|
|
2023-07-04 19:53:26 +02:00
|
|
|
map_choice = bpf_map_lookup_elem(&map_active_agg_instance, &zero);
|
|
|
|
if (!map_choice)
|
|
|
|
return NULL;
|
|
|
|
|
2023-07-04 17:34:41 +02:00
|
|
|
if (ipv == AF_INET) {
|
|
|
|
create_ipprefix_key_v4(&key.v4, ip);
|
2023-07-04 19:53:26 +02:00
|
|
|
agg_map = *map_choice == 0 ? (void *)&map_v4_agg1 :
|
|
|
|
(void *)&map_v4_agg2;
|
2023-07-04 17:34:41 +02:00
|
|
|
} else {
|
|
|
|
create_ipprefix_key_v6(&key.v6, ip);
|
2023-07-04 19:53:26 +02:00
|
|
|
agg_map = *map_choice == 0 ? (void *)&map_v6_agg1 :
|
|
|
|
(void *)&map_v6_agg2;
|
2023-07-04 17:34:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
agg = bpf_map_lookup_elem(agg_map, &key);
|
|
|
|
if (agg)
|
|
|
|
return agg;
|
|
|
|
|
|
|
|
// No existing entry, try to create new one
|
|
|
|
err = bpf_map_update_elem(agg_map, &key, &empty_stats, BPF_NOEXIST);
|
2023-06-16 20:11:14 +02:00
|
|
|
if (err && err != -EEXIST) {
|
|
|
|
// No space left in aggregation map - switch to backup entry
|
|
|
|
if (ipv == AF_INET)
|
|
|
|
key.v4 = IPV4_BACKUP_KEY;
|
|
|
|
else
|
|
|
|
key.v6 = IPV6_BACKUP_KEY;
|
|
|
|
}
|
2023-07-04 17:34:41 +02:00
|
|
|
|
|
|
|
return bpf_map_lookup_elem(agg_map, &key);
|
|
|
|
}
|
|
|
|
|
2023-10-17 16:23:51 +02:00
|
|
|
static void aggregate_rtt(__u64 rtt, struct aggregated_stats *agg_stats)
|
2023-07-04 17:34:41 +02:00
|
|
|
{
|
2023-05-30 16:18:13 +02:00
|
|
|
if (!config.agg_rtts || !agg_stats)
|
2023-07-04 17:34:41 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
int bin_idx;
|
|
|
|
|
2023-10-17 16:23:51 +02:00
|
|
|
if (!agg_stats->rtt_min || rtt < agg_stats->rtt_min)
|
|
|
|
agg_stats->rtt_min = rtt;
|
|
|
|
if (rtt > agg_stats->rtt_max)
|
|
|
|
agg_stats->rtt_max = rtt;
|
2023-07-04 17:34:41 +02:00
|
|
|
|
|
|
|
bin_idx = rtt / RTT_AGG_BIN_WIDTH;
|
|
|
|
bin_idx = bin_idx >= RTT_AGG_NR_BINS ? RTT_AGG_NR_BINS - 1 : bin_idx;
|
2023-10-17 16:23:51 +02:00
|
|
|
agg_stats->rtt_bins[bin_idx]++;
|
2023-07-04 17:34:41 +02:00
|
|
|
}
|
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
/*
|
|
|
|
* Attempt to create a timestamp-entry for packet p_info for flow in f_state
|
|
|
|
*/
|
|
|
|
static void pping_timestamp_packet(struct flow_state *f_state, void *ctx,
|
2022-11-04 13:41:47 +01:00
|
|
|
struct packet_info *p_info)
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
{
|
2022-03-22 17:59:18 +01:00
|
|
|
if (!is_flowstate_active(f_state) || !p_info->pid_valid)
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
return;
|
|
|
|
|
2022-05-31 21:19:19 +02:00
|
|
|
if (config.localfilt && p_info->is_ingress &&
|
|
|
|
is_local_address(p_info, ctx))
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
return;
|
2021-05-07 14:54:12 +02:00
|
|
|
|
2021-04-15 14:13:54 +02:00
|
|
|
// Check if identfier is new
|
2022-11-04 13:41:47 +01:00
|
|
|
if ((f_state->has_been_timestamped || p_info->wait_first_edge) &&
|
|
|
|
!is_new_identifier(&p_info->pid, f_state))
|
2021-12-08 10:06:30 +01:00
|
|
|
return;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
f_state->last_id = p_info->pid.identifier;
|
2021-04-15 14:13:54 +02:00
|
|
|
|
|
|
|
// Check rate-limit
|
2022-11-04 13:41:47 +01:00
|
|
|
if (f_state->has_been_timestamped &&
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
is_rate_limited(p_info->time, f_state->last_timestamp,
|
2022-02-10 16:11:21 +01:00
|
|
|
config.use_srtt ? f_state->srtt : f_state->min_rtt))
|
2021-12-08 10:06:30 +01:00
|
|
|
return;
|
2021-04-15 14:13:54 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Updates attempt at creating timestamp, even if creation of timestamp
|
|
|
|
* fails (due to map being full). This should make the competition for
|
|
|
|
* the next available map slot somewhat fairer between heavy and sparse
|
|
|
|
* flows.
|
|
|
|
*/
|
2022-11-04 13:41:47 +01:00
|
|
|
f_state->has_been_timestamped = true;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
f_state->last_timestamp = p_info->time;
|
2021-04-15 14:13:54 +02:00
|
|
|
|
2022-02-03 15:51:22 +01:00
|
|
|
if (bpf_map_update_elem(&packet_ts, &p_info->pid, &p_info->time,
|
2022-03-09 22:19:59 +01:00
|
|
|
BPF_NOEXIST) == 0)
|
|
|
|
__sync_fetch_and_add(&f_state->outstanding_timestamps, 1);
|
|
|
|
else
|
2022-02-03 15:51:22 +01:00
|
|
|
send_map_full_event(ctx, p_info, PPING_MAP_PACKETTS);
|
2021-04-15 14:13:54 +02:00
|
|
|
}
|
|
|
|
|
2021-12-08 10:06:30 +01:00
|
|
|
/*
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
* Attempt to match packet in p_info with a timestamp from flow in f_state
|
2021-12-08 10:06:30 +01:00
|
|
|
*/
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
static void pping_match_packet(struct flow_state *f_state, void *ctx,
|
2023-05-30 16:18:13 +02:00
|
|
|
struct packet_info *p_info,
|
2023-10-17 16:23:51 +02:00
|
|
|
struct aggregated_stats *agg_stats)
|
2021-04-15 14:13:54 +02:00
|
|
|
{
|
2022-09-27 13:46:34 +02:00
|
|
|
__u64 rtt;
|
2021-12-08 10:06:30 +01:00
|
|
|
__u64 *p_ts;
|
2021-04-15 14:13:54 +02:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
if (!is_flowstate_active(f_state) || !p_info->reply_pid_valid)
|
2021-12-08 10:06:30 +01:00
|
|
|
return;
|
2021-04-15 14:13:54 +02:00
|
|
|
|
2022-03-09 22:19:59 +01:00
|
|
|
if (f_state->outstanding_timestamps == 0)
|
|
|
|
return;
|
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
p_ts = bpf_map_lookup_elem(&packet_ts, &p_info->reply_pid);
|
|
|
|
if (!p_ts || p_info->time < *p_ts)
|
2021-12-08 10:06:30 +01:00
|
|
|
return;
|
2021-05-07 14:54:12 +02:00
|
|
|
|
2022-09-27 13:46:34 +02:00
|
|
|
rtt = p_info->time - *p_ts;
|
2022-02-17 14:01:08 +01:00
|
|
|
|
2021-05-06 17:54:31 +02:00
|
|
|
// Delete timestamp entry as soon as RTT is calculated
|
2022-03-09 22:19:59 +01:00
|
|
|
if (bpf_map_delete_elem(&packet_ts, &p_info->reply_pid) == 0) {
|
|
|
|
__sync_fetch_and_add(&f_state->outstanding_timestamps, -1);
|
2022-02-17 14:01:08 +01:00
|
|
|
debug_increment_autodel(PPING_MAP_PACKETTS);
|
2022-03-09 22:19:59 +01:00
|
|
|
}
|
2021-04-15 14:13:54 +02:00
|
|
|
|
2022-09-27 13:46:34 +02:00
|
|
|
if (f_state->min_rtt == 0 || rtt < f_state->min_rtt)
|
|
|
|
f_state->min_rtt = rtt;
|
|
|
|
f_state->srtt = calculate_srtt(f_state->srtt, rtt);
|
|
|
|
|
|
|
|
send_rtt_event(ctx, rtt, f_state, p_info);
|
2023-05-30 16:18:13 +02:00
|
|
|
aggregate_rtt(rtt, agg_stats);
|
|
|
|
}
|
|
|
|
|
2023-10-17 16:23:51 +02:00
|
|
|
static void update_aggregate_stats(struct aggregated_stats **src_stats,
|
|
|
|
struct aggregated_stats **dst_stats,
|
2023-05-30 16:18:13 +02:00
|
|
|
struct packet_info *p_info)
|
|
|
|
{
|
|
|
|
if (!config.agg_rtts)
|
|
|
|
return;
|
|
|
|
|
|
|
|
*src_stats = lookup_or_create_aggregation_stats(
|
|
|
|
&p_info->pid.flow.saddr.ip, p_info->pid.flow.ipv);
|
|
|
|
if (*src_stats) {
|
|
|
|
(*src_stats)->last_updated = p_info->time;
|
pping: Reverse the interpretation of rx/tx for aggregated stats
For the aggregated stats, report RX and TX from the perspective of the
capture point, instead of the perspective of the subnet.
Consider the following setup, consisting of subnet A, the capture
point (CP) where we're running ePPing, and subnet B.
A <-----> CP <-----> B
Now consider that we have a TCP stream uploading data from A to B, so
that we can capture RTTs between when the data packet from A reaches
CP to when the ACK from B gets back to the CP, i.e. CP -> B -> CP.
Previously, the RX stats for a subnet referred to packets received by
the subnet, i.e. packets with dst address in the subnet. Likewise, TX
packets were packets transmitted by the subnet, i.e. packets with src
address in the subnet. So the data packet from A -> B would be
reported as TX for subnet A and RX for subnet B.
However, the RTTs are by default (can be changed by the
--aggregate-reverse flag) aggregated from the perspective of the
capture point, so that the RTT CP -> B -> CP would be reported as an
RTT observed for subnet B.
Make the TX and RX stats consistent with the RTT, so that all subnet
stats are from the perspective of the CP. Make RX refer to packets the
CP has received from the subnet, i.e. packets with src in A, and TX
refer to packets the CP has transmitted to the subnet, i.e. packets
with dst in the subnet. So report a data packet from A -> B as RX for
subnet A and TX for subnet B.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2023-10-17 16:54:43 +02:00
|
|
|
(*src_stats)->rx_packet_count++;
|
|
|
|
(*src_stats)->rx_byte_count += p_info->pkt_len;
|
2023-05-30 16:18:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
*dst_stats = lookup_or_create_aggregation_stats(
|
|
|
|
&p_info->pid.flow.daddr.ip, p_info->pid.flow.ipv);
|
|
|
|
if (*dst_stats) {
|
|
|
|
(*dst_stats)->last_updated = p_info->time;
|
pping: Reverse the interpretation of rx/tx for aggregated stats
For the aggregated stats, report RX and TX from the perspective of the
capture point, instead of the perspective of the subnet.
Consider the following setup, consisting of subnet A, the capture
point (CP) where we're running ePPing, and subnet B.
A <-----> CP <-----> B
Now consider that we have a TCP stream uploading data from A to B, so
that we can capture RTTs between when the data packet from A reaches
CP to when the ACK from B gets back to the CP, i.e. CP -> B -> CP.
Previously, the RX stats for a subnet referred to packets received by
the subnet, i.e. packets with dst address in the subnet. Likewise, TX
packets were packets transmitted by the subnet, i.e. packets with src
address in the subnet. So the data packet from A -> B would be
reported as TX for subnet A and RX for subnet B.
However, the RTTs are by default (can be changed by the
--aggregate-reverse flag) aggregated from the perspective of the
capture point, so that the RTT CP -> B -> CP would be reported as an
RTT observed for subnet B.
Make the TX and RX stats consistent with the RTT, so that all subnet
stats are from the perspective of the CP. Make RX refer to packets the
CP has received from the subnet, i.e. packets with src in A, and TX
refer to packets the CP has transmitted to the subnet, i.e. packets
with dst in the subnet. So report a data packet from A -> B as RX for
subnet A and TX for subnet B.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2023-10-17 16:54:43 +02:00
|
|
|
(*dst_stats)->tx_packet_count++;
|
|
|
|
(*dst_stats)->tx_byte_count += p_info->pkt_len;
|
2023-05-30 16:18:13 +02:00
|
|
|
}
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
}
|
2021-04-15 14:13:54 +02:00
|
|
|
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
/*
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
* Contains the actual pping logic that is applied after a packet has been
|
|
|
|
* parsed and deemed to contain some valid identifier.
|
|
|
|
|
|
|
|
* Looks up and updates flowstate (in both directions), tries to save a
|
|
|
|
* timestamp of the packet, tries to match packet against previous timestamps,
|
|
|
|
* calculates RTTs and pushes messages to userspace as appropriate.
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
*/
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
static void pping_parsed_packet(void *ctx, struct packet_info *p_info)
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
{
|
2022-03-22 17:59:18 +01:00
|
|
|
struct dual_flow_state *df_state;
|
|
|
|
struct flow_state *fw_flow, *rev_flow;
|
2023-10-17 16:23:51 +02:00
|
|
|
struct aggregated_stats *src_stats = NULL, *dst_stats = NULL;
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
|
2022-11-04 13:41:47 +01:00
|
|
|
df_state = lookup_or_create_dualflow_state(ctx, p_info);
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
if (!df_state)
|
pping: Do both timestamping and matching on ingress and egress
Perform both timestamping and matching on both ingress and egress
hooks. This makes it more similar to Kathie's pping, allowing the tool
to capture RTTs in both directions when deployed on just a single
interface.
Like Kathie's pping, by default filter out RTTs for packets going to
the local machine (will only include local processing delays). This
behavior can be disabled by passing the -l/--include-local option.
As packets that are timestamped on ingress and matched on egress will
include the local machines processing delay, add the "match_on_egress"
member to the JSON output that can be used to differentiate between
RTTs that include the local processing delay, and those which don't.
Finally, report the source and destination addresses from the perspective
of the reply packet, rather than the timestamped packet, to be
consistent with Kathie's pping.
Overall, refactor large parts of pping_kern to allow both timestamping
and matching, as well as updating both the flow and reverse flow and
handle flow-events related to them, in one go. Also update README to
reflect changes.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-02-10 16:16:24 +01:00
|
|
|
return;
|
|
|
|
|
2023-05-30 16:18:13 +02:00
|
|
|
update_aggregate_stats(&src_stats, &dst_stats, p_info);
|
|
|
|
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
fw_flow = get_flowstate_from_packet(df_state, p_info);
|
2022-11-04 13:41:47 +01:00
|
|
|
update_forward_flowstate(p_info, fw_flow);
|
|
|
|
pping_timestamp_packet(fw_flow, ctx, p_info);
|
2022-05-31 21:19:19 +02:00
|
|
|
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
rev_flow = get_reverse_flowstate_from_packet(df_state, p_info);
|
|
|
|
update_reverse_flowstate(ctx, p_info, rev_flow);
|
2023-05-30 16:18:13 +02:00
|
|
|
pping_match_packet(rev_flow, ctx, p_info,
|
|
|
|
config.agg_by_dst ? dst_stats : src_stats);
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
|
|
|
|
close_and_delete_flows(ctx, p_info, fw_flow, rev_flow);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Main function which contains all the pping logic (parse packet, attempt to
|
|
|
|
* create timestamp for it, try match against previous timestamps, update
|
|
|
|
* flowstate etc.).
|
|
|
|
*
|
|
|
|
* Has a separate tc and xdp version so that verifier sees the global
|
|
|
|
* functions for parsing packets in the right context, but most of the
|
|
|
|
* work is done in common functions (parse_packet_identifier and
|
|
|
|
* pping_parsed_packet)
|
|
|
|
*/
|
|
|
|
static void pping_tc(struct __sk_buff *ctx, bool is_ingress)
|
|
|
|
{
|
|
|
|
struct packet_info p_info = { 0 };
|
|
|
|
|
|
|
|
if (parse_packet_identifer_tc(ctx, &p_info) < 0)
|
2022-03-22 17:59:18 +01:00
|
|
|
return;
|
|
|
|
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
p_info.is_ingress = is_ingress;
|
|
|
|
p_info.ingress_ifindex = is_ingress ? ctx->ingress_ifindex : 0;
|
|
|
|
|
|
|
|
pping_parsed_packet(ctx, &p_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pping_xdp(struct xdp_md *ctx)
|
|
|
|
{
|
|
|
|
struct packet_info p_info = { 0 };
|
|
|
|
|
|
|
|
if (parse_packet_identifer_xdp(ctx, &p_info) < 0)
|
|
|
|
return;
|
2022-02-03 12:03:22 +01:00
|
|
|
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
p_info.is_ingress = true;
|
2022-11-03 19:53:03 +01:00
|
|
|
p_info.ingress_ifindex = ctx->ingress_ifindex;
|
pping: Add timestamp and min-RTT to output
To add timestamp to output, push the timestamp when packet was
processed from kernel as part of the rtt-event. Also keep track of
minimum encountered RTT for each flow in kernel, and also push that as
part of the RTT-event.
Additionally, avoid pushing RTT messages at all if no flow-state
information can be found (due to ex. being deleted from egress side),
as no valid min-RTT can then be given. Furthermore, no longer delete
flow-information once seeing the FIN-flag on egress in order to keep
useful flow-state around for RTT-messages longer. Due to the
FIN-handshake process, it is sufficient if the ingress program deletes
the flow-state upon seeing FIN. However, still delete flow-state from
either ingress or egress upon seeing RST flag, as RST does not have a
handshake process allowing for delayed deletion.
While minimum RTT could also be tracked from the userspace process,
userspace is not aware of when the flow is closed so would have to add
additional logic to keep track of minimum RTT for each flow and
periodically clean them up. Furthermore, keeping RTT statistics in the
flow-state map is useful for implementing future features, such as an
RTT-based sampling interval. It would also be useful in case pping is
changed to no longer have a long-running userspace process printing
out all the calculated RTTs, but instead simply occasionally looks up
the RTT from the flow-state map.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2021-04-29 18:55:06 +02:00
|
|
|
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
pping_parsed_packet(ctx, &p_info);
|
2022-03-22 17:59:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool is_flow_old(struct network_tuple *flow, struct flow_state *f_state,
|
|
|
|
__u64 time)
|
|
|
|
{
|
|
|
|
__u64 age;
|
|
|
|
__u64 ts;
|
|
|
|
|
|
|
|
if (!f_state || !is_flowstate_active(f_state))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
ts = f_state->last_timestamp; // To avoid concurrency issue between check and age calculation
|
|
|
|
if (ts > time)
|
|
|
|
return false;
|
|
|
|
age = time - ts;
|
|
|
|
|
2022-03-30 17:40:54 +02:00
|
|
|
return (f_state->conn_state == CONNECTION_STATE_WAITOPEN &&
|
|
|
|
age > UNOPENED_FLOW_LIFETIME) ||
|
2022-03-22 17:59:18 +01:00
|
|
|
((flow->proto == IPPROTO_ICMP ||
|
|
|
|
flow->proto == IPPROTO_ICMPV6) &&
|
|
|
|
age > ICMP_FLOW_LIFETIME) ||
|
|
|
|
age > FLOW_LIFETIME;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void send_flow_timeout_message(void *ctx, struct network_tuple *flow,
|
|
|
|
__u64 time)
|
|
|
|
{
|
2023-07-04 17:34:41 +02:00
|
|
|
if (!config.push_individual_events)
|
|
|
|
return;
|
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
struct flow_event fe = {
|
|
|
|
.event_type = EVENT_TYPE_FLOW,
|
|
|
|
.flow_event_type = FLOW_EVENT_CLOSING,
|
|
|
|
.reason = EVENT_REASON_FLOW_TIMEOUT,
|
|
|
|
.source = EVENT_SOURCE_GC,
|
|
|
|
.timestamp = time,
|
|
|
|
.reserved = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
// To be consistent with Kathie's pping we report flow "backwards"
|
|
|
|
reverse_flow(&fe.flow, flow);
|
|
|
|
|
|
|
|
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &fe, sizeof(fe));
|
2021-12-08 10:06:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Programs
|
|
|
|
|
|
|
|
// Egress path using TC-BPF
|
2022-01-04 17:08:10 +01:00
|
|
|
SEC("tc")
|
2021-12-08 10:06:30 +01:00
|
|
|
int pping_tc_egress(struct __sk_buff *skb)
|
|
|
|
{
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
pping_tc(skb, false);
|
2021-12-08 10:06:30 +01:00
|
|
|
|
2021-12-17 18:03:00 +01:00
|
|
|
return TC_ACT_UNSPEC;
|
2021-12-08 10:06:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Ingress path using TC-BPF
|
2022-01-04 17:08:10 +01:00
|
|
|
SEC("tc")
|
2021-12-08 10:06:30 +01:00
|
|
|
int pping_tc_ingress(struct __sk_buff *skb)
|
|
|
|
{
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
pping_tc(skb, true);
|
2021-12-08 10:06:30 +01:00
|
|
|
|
2021-12-17 18:03:00 +01:00
|
|
|
return TC_ACT_UNSPEC;
|
2021-12-08 10:06:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Ingress path using XDP
|
2022-01-04 17:08:10 +01:00
|
|
|
SEC("xdp")
|
2021-12-08 10:06:30 +01:00
|
|
|
int pping_xdp_ingress(struct xdp_md *ctx)
|
|
|
|
{
|
pping: Make packet parsing a global function
Use global functions to make use of function-by-function verification.
This allows the verifier to analyze parts of the program individually
from each other, which should help reduce the verification
complexity (the number of instructions the verifier must go through to
verify the program) and help prevent exponentially growing with every
loop or branch added to the code.
In this case, break out the packet parsing (parse_packet_identifier)
as a global function, so that it can be handled separately from the
logic after it (updating flow state, saving timestamps, matching
replies to timestamps, calculating and pushing RTTs) etc. To do this,
create small separate wrapper functions (parse_packet_identifier_tc()
and parse_packet_identifier_xdp()) for tc/xdp, so that the verifier
can correctly identify the arguments as pointers to
context (PTR_TO_CTX) when evaluating the global functions. Also create
small wrapper functions pping_tc() and pping_xdp() which call the
corresponding parse_packet_identifier_tc/xdp function.
For this to work in XDP mode (which is the default), the kernel must
have been patched with a fix that addresses an issue with how global
functions are verified for XDP programs, see:
https://lore.kernel.org/all/20220606075253.28422-1-toke@redhat.com/
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:58:59 +02:00
|
|
|
pping_xdp(ctx);
|
2021-12-08 10:06:30 +01:00
|
|
|
|
2021-04-15 14:13:54 +02:00
|
|
|
return XDP_PASS;
|
|
|
|
}
|
2022-03-09 19:28:05 +01:00
|
|
|
|
|
|
|
SEC("iter/bpf_map_elem")
|
|
|
|
int tsmap_cleanup(struct bpf_iter__bpf_map_elem *ctx)
|
|
|
|
{
|
|
|
|
struct packet_id local_pid;
|
2022-11-08 17:45:34 +01:00
|
|
|
struct flow_state *f_state = NULL;
|
2022-03-22 17:59:18 +01:00
|
|
|
struct dual_flow_state *df_state;
|
|
|
|
struct network_tuple df_key;
|
2022-03-09 19:28:05 +01:00
|
|
|
struct packet_id *pid = ctx->key;
|
|
|
|
__u64 *timestamp = ctx->value;
|
|
|
|
__u64 now = bpf_ktime_get_ns();
|
2022-02-17 14:11:40 +01:00
|
|
|
__u64 rtt;
|
2022-03-09 19:28:05 +01:00
|
|
|
|
2022-02-17 14:01:08 +01:00
|
|
|
debug_update_mapclean_stats(ctx, &events, !ctx->key || !ctx->value,
|
|
|
|
ctx->meta->seq_num, now,
|
|
|
|
PPING_MAP_PACKETTS);
|
|
|
|
|
2022-03-09 19:28:05 +01:00
|
|
|
if (!pid || !timestamp)
|
|
|
|
return 0;
|
2022-02-17 14:11:40 +01:00
|
|
|
if (now <= *timestamp)
|
|
|
|
return 0;
|
2022-03-09 19:28:05 +01:00
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
make_dualflow_key(&df_key, &pid->flow);
|
|
|
|
df_state = bpf_map_lookup_elem(&flow_state, &df_key);
|
2022-11-08 17:45:34 +01:00
|
|
|
if (df_state)
|
|
|
|
f_state = get_flowstate_from_dualflow(df_state, &pid->flow);
|
2022-02-17 14:11:40 +01:00
|
|
|
rtt = f_state ? f_state->srtt : 0;
|
2022-02-17 14:01:08 +01:00
|
|
|
|
2022-02-17 14:11:40 +01:00
|
|
|
if ((rtt && now - *timestamp > rtt * TIMESTAMP_RTT_LIFETIME) ||
|
|
|
|
now - *timestamp > TIMESTAMP_LIFETIME) {
|
2022-03-22 17:59:18 +01:00
|
|
|
/* Seems like the key for map lookup operations must be
|
|
|
|
on the stack, so copy pid to local_pid. */
|
|
|
|
__builtin_memcpy(&local_pid, pid, sizeof(local_pid));
|
2022-03-09 22:19:59 +01:00
|
|
|
if (bpf_map_delete_elem(&packet_ts, &local_pid) == 0) {
|
2022-02-17 14:01:08 +01:00
|
|
|
debug_increment_timeoutdel(PPING_MAP_PACKETTS);
|
2022-03-09 22:19:59 +01:00
|
|
|
|
|
|
|
if (f_state)
|
|
|
|
__sync_fetch_and_add(
|
|
|
|
&f_state->outstanding_timestamps, -1);
|
|
|
|
}
|
2022-03-09 19:28:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SEC("iter/bpf_map_elem")
|
|
|
|
int flowmap_cleanup(struct bpf_iter__bpf_map_elem *ctx)
|
|
|
|
{
|
2022-03-22 17:59:18 +01:00
|
|
|
struct network_tuple flow1, flow2;
|
|
|
|
struct flow_state *f_state1, *f_state2;
|
|
|
|
struct dual_flow_state *df_state;
|
2022-03-09 19:28:05 +01:00
|
|
|
__u64 now = bpf_ktime_get_ns();
|
2022-03-22 17:59:18 +01:00
|
|
|
bool notify1, notify2, timeout1, timeout2;
|
2022-03-09 19:28:05 +01:00
|
|
|
|
2022-02-17 14:01:08 +01:00
|
|
|
debug_update_mapclean_stats(ctx, &events, !ctx->key || !ctx->value,
|
|
|
|
ctx->meta->seq_num, now,
|
|
|
|
PPING_MAP_FLOWSTATE);
|
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
if (!ctx->key || !ctx->value)
|
2022-02-17 14:11:40 +01:00
|
|
|
return 0;
|
|
|
|
|
2022-03-22 17:59:18 +01:00
|
|
|
flow1 = *(struct network_tuple *)ctx->key;
|
|
|
|
reverse_flow(&flow2, &flow1);
|
|
|
|
|
|
|
|
df_state = ctx->value;
|
|
|
|
f_state1 = get_flowstate_from_dualflow(df_state, &flow1);
|
|
|
|
f_state2 = get_flowstate_from_dualflow(df_state, &flow2);
|
|
|
|
|
|
|
|
timeout1 = is_flow_old(&flow1, f_state1, now);
|
|
|
|
timeout2 = is_flow_old(&flow2, f_state2, now);
|
|
|
|
|
|
|
|
if ((!is_flowstate_active(f_state1) || timeout1) &&
|
|
|
|
(!is_flowstate_active(f_state2) || timeout2)) {
|
|
|
|
// Entry should be deleted
|
|
|
|
notify1 = should_notify_closing(f_state1) && timeout1;
|
|
|
|
notify2 = should_notify_closing(f_state2) && timeout2;
|
|
|
|
if (bpf_map_delete_elem(&flow_state, &flow1) == 0) {
|
2022-05-25 16:40:28 +02:00
|
|
|
debug_increment_timeoutdel(PPING_MAP_FLOWSTATE);
|
2022-03-22 17:59:18 +01:00
|
|
|
if (notify1)
|
|
|
|
send_flow_timeout_message(ctx, &flow1, now);
|
|
|
|
if (notify2)
|
|
|
|
send_flow_timeout_message(ctx, &flow2, now);
|
2022-03-09 19:28:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|