When both BPF programs are kept in the same file, no longer need to
pin the maps in order to share them between the programs.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Merge the pping_kern_tc.c, pping_kern_xdp.c and pping_helpers.h into
the single file pping_kern.c. Do not change any of the BPF code,
except renaming the map ts_start to packet_ts.
To handle both BPF programs kept in single ELF-file, change loading
mechanism to extract and attach both tc and XDP programs from it. Also
refactor main-method into several smaller functions to reduce its
size.
Finally, added the --force (-f) and --cleanup-interval (-c) options to
the argument parsing, and improved the parsing of the
--rate-limit (-r) option.
NOTE: The verifier rejects program in it's current state as too
large (over 1 million instructions). Setting the TCP_MAX_OPTIONS in
pping_kern.c to 5 (or less) solves this. Unsure at the moment what
causes the verifier to think the program is so large, as the code in
pping_kern.c is identical to the one from the three files it was
merged from.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Refactor init_rodata to search for the first map with ".rodata" in its
name. Should be more robust than previous solution which first tried
to construct the name for the rodata map, and then find the map by
name.
Also remove some outcommented code that was not used.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Implement basic mechanic for parsing arguments from userspace and
passing them to a global config variable in the BPF programs.
This also changes the basic use of the program from:
$./pping interface
to:
$./pping -i interface
Also, revert to using the memset solution for the map_ipv4_to_ipv6
function to avoid the ipv4_prefix constant being stored in the .rodata
section. This makes it easier to set the value for the global config
variable from userspace, as the only thing left in the .rodata section
is the config struct.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Remove some out-commented code. Also use bpf_object__unpin_maps
instead of manually unpinning the ts_start map. Additionally, change
map_ipv4_to_ipv6 to use clearer implementation (that now also works
for tc due to always using libbpf to load program).
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Load and pin the tc-bpf program in pping.c using libbpf, and only
attach the pinned program using iproute. That way, can use features
that are not supported by the old iproute loader, even if iproute does
not have libbpf support.
To support this change, extend bpf_egress_loader with option to load
pinned program. Additionally, remove configure script and parts of
Makefile that are no longer needed. Furthermore, remove multiple
definitions of ts_start map, and place singular definition in
pping_helpers.h which is included by both BPF programs.
Also, some minor fixes based on Toke's review.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Add a per-flow rate limit, limiting how often new timestamp entries
can be created. As part of this, add per-flow state keeping track
of when last timestamp was created and last seen identifier for each
flow.
Additionally, remove timestamp entry as soon as RTT is
calculated, as last seen identifier is used to find first unique value
instead. Furthermore, remove packet_timestamp struct and only use
__u64 as timestamp, as used memeber is no longer needed.
This initial commit lacks cleanup of flow-state, user-configuration of
rate limit, mechanism to handle bursts etc.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Refactor TC and XDP programs to reuse common logic for parsing
packets. Add functions for parsing packets for an identifier to
pping_helpers.h which both TC and XDP parts use. Also make it easier
to extend pping with support for new protocols, as only new parsing
functions have to be added and inserted into a single place.
Also add reserved members to end of structs in pping.h to indicate
padding.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Move some members in network_tuple and rtt_event around to avoid holes.
Also remove some uncecessary parentheses before & operator, and add
local definitions of AF_INET and AF_INET6.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Several changes to add IPv6 support:
- Change structs in pping.h
- replace ipv4_flow with network_tuple
- rename ts_key to packet_id
- rename ts_timestamp to packet_timestamp
- Add map_ipv4_to_ipv4 in pping_helpers.h
- Also remove obsolete fill_ipv4_flow
- Rewrite pping_kern*
- parse either IPv4 or IPv6 header (depending on proto)
- Use map_ipv4_to_ipv6 to store IPv4 address in network_tuple
Support printout of IPv6 addresses in pping.c
- Add function format_ip_address as wrapper over inet_ntop
- Change handle_rtt_event to first format IP-address strings in
local buffers, then perform single printout
While some steps have been taken to be more general towards different
types of packet identifiers (not just the currently supported TCP
timestamps), significant refactorization of pping_kern* will still be
required. Also, pping_kern_xdp and pping_kern_tc also have large
sections of very similar code that can be refactored into functions.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Create the /sys/fs/bpf/tc folder if it does not exist. Also check if
pping is run as root, otherwise inform user that it must run as root.
Libbpf will attempt to create the /sys/fs/bpf/tc/globals directory
when pinning the map, however it will not do so recursivly (so will
fail if /sys/fs/bpf/tc does not exist). So as a temporary solution,
attempt to create /sys/fs/bpf/tc (however, if sys/fs/bpf is not
mounted this will still fail).
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Refactor tc_bpf_load and tc_bpf_clear to use a common run_program
function which does the fork+execv.
Enclose compound statement defines in parenthesis.
Removed argument CLOCK_MONOTONIC from callers to parameterless
function get_time_ns().
Also fix some weird spacing in pping_helpers.h, and fix some
formatting issues, using clang-format with the kernel source tree
.clang-format on the whole tree.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Perform various fixes and tweaks:
- Rename several defines to make them more informative
- Remove unrolling of loop in BPF programs
- Reuse defines for program sections between userspace and kernel
space programs
- Perform fork+exec to run bpf_egress_loader script instead of
system()
- Add comment to copied scripts indicating I've modified them
- Add pping.h and pping_helpers.h as dependencies in Makefile
Also, add a brief description of what PPing is and how it works to
README
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Split the print statements for RTTs into two parts to avoid inet_ntoa
overwriting one of the IP-addresses (causing both source and
destitionation address to appear the same). Also flip the order of
source and destination to be the same as Pollere's pping.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Switch order so XDP program loads first, so the ts_start map is
automatically pinned by libbpf (solves issue with tc not preserving
the name of the map).
Unload the TCP-BPF program (or rather remove the entire clsact qdisc
it is attached to) using bpg_egress_loader script once program
exits. Also unpin ts_start map on program shutdown.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Make loader use libbpf's existing functionality for reusing pinned
maps. The name for map not kept by tc, so cannot get fd of map by
name. Use fd of first encountered map as temporary workaround.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Format the code using the .clang-format from the kernel source tree,
with a few manual tweaks here and there. Also, remove the TODO list
from comment of pping.c and instead put it in TODO.md.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Make tc pin the ts_start map when loading the TC-BPF program, and
rewrite XDP loader to reuse map pinned by tc.
Also add comment with TODO list in pping.c.
Testing pping by adding a delay through a netem qdisc in the test
environment shows that the reported RTT will approach 100ms for any
delay lower than 100ms, but the correct RTT for any delay over
100ms. Root cause is unknown, but Pollere's original pping
implementation (as well as a bpftrace based pping implementation)
shows the same issue. This issue has not been observed when running on
real interfaces without a netem qdisc.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
Split and rename files so there is one userspace program (pping) and
two kernel-space ones (one for XDP and one for TC-BPF).
Copy the shell script for loading the TC-BPF program from
traffic-pacing-edt folder, but add support for loading a specific
section.
The XDP and TC-BPF programs do not share the ts_start map, so program
does not work.
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>