Commit Graph

508 Commits

Author SHA1 Message Date
Toke Høiland-Jørgensen
e9aeda404e pkt-loop-filter: fix ethernet multicast frame identification
Multicast, which also includes broadcast, frames can be identified by
looking at the LSB of the first octet of the destination MAC address.

Original-patch-by: Jonathan Toppins <jtoppins@redhat.com>
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-06-29 16:58:34 +02:00
Toke Høiland-Jørgensen
1b38fda8fb Merge pull request #48 from simosund/pping-debugcount-fix
pping: Add missing debug timeout count
2022-06-21 21:17:36 +02:00
Toke Høiland-Jørgensen
99abd7a8a1 Merge pull request #47 from simosund/pping-reduce-verification-complexity
pping - Reduce verification complexity
2022-06-21 21:17:25 +02:00
Simon Sundberg
3c698076ee pping: Add missing debug timeout count
The debug counter for timed out (deleted by periodical cleanup) flow
states was never incremented, so fix that.

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 19:00:34 +02:00
Simon Sundberg
add888566d 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
Simon Sundberg
404a70c524 pping: Remove packet pointers from packet_info
Do not provide pointers into the original packet from packet_info
anymore (which the verifier has to ensure are valid), and instead
directly parse all necessary data in parse_packet_identifier and then
only use the parsed data in later functions.

This allows a cleaner separation of concerns, where the parsing
functions parse all necessary data from the packets, and other
functions that need information about the packet only rely on the data
provided in packet_info (and do not attempt to parse any data on their
own).

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-21 17:33:58 +02:00
Toke Høiland-Jørgensen
96a5c2ebbf pkt-loop-filter: Set map size from userspace instead of in BPF definition
With this we can add a command line parameter to dynamically size the map
later.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-06-14 17:43:39 +02:00
Toke Høiland-Jørgensen
60ed7a8e8b pkt-loop-filter: Filter multicast traffic
This adds filtering of multicast traffic to the set of interfaces. The
filtering works by marking one of the interfaces as "primary" (which is
just the first interface name that is supplied on the command line) and
filtering everything with an all-ones destination MAC address if it's
coming in on any interface that's not the primary one.

To handle interfaces going down, we actually supply all the ifindexes to
the BPF program, and also install a tracing hook that listens to ifdown
events and switches the logic to the next ifindex in the sequence if the
primary one goes down. This is a bit rudimentary but should at least
provide basic filtering.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-06-14 17:43:35 +02:00
Toke Høiland-Jørgensen
50f3609658 pkt-loop-filter: Switch to using BPF skeletons
This makes it easier to populate the global variables we'll need for
handling multicast, and also means we don't have to worry about keeping the
BPF object file around (since it'll be statically linked).

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-06-14 17:43:35 +02:00
Toke Høiland-Jørgensen
c57a5bc169 pkt-loop-filter: Attach a tracing program to catch ifdown events
This is needed to be able to react to interfaces going down so we can
allow multicast on a secondary interface if the primary goes down. We don't
actually react to the event yet, just print it; handling this will be added
in a subsequent commit.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-06-14 17:43:31 +02:00
Simon Sundberg
aaf6036655 pping: Move some info from parsing_context to packet_info
Remove the is_egress and ingress_ifindex from the parsing_context
struct to the packet_info struct. Also change the member is_egress to
is_ingress to better fit with the ingress_ifindex member.

These members were only in parsing_context because they were
convenient to fill in right from the start. However, it semantically
makes little sense for the parsing_context to contain these because
they are not used for any parsing, and they fit better with the
packet_info. This also allows later functions (is_local_address(),
pping_timestamp_packet() and pping_match_packet()) to get rid of their
dependency on parsing_context, as it was only used for the is_egress
and ingress_ifindex members (they do not do any parsing). After this
change, parsing_context is only used for the initial parsing, and
packet_info contains all the necessary data for all the functions
related to the pping logic that runs after the packet has been parsed.

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-06-10 17:01:14 +02:00
Toke Høiland-Jørgensen
fc18074b31 Merge pull request #44 from xdp-project/pping-libxdp
pping: Use libxdp to load and attach XDP program
2022-05-26 13:46:13 +02:00
Toke Høiland-Jørgensen
070715cf1c Add pkt-loop-filter example
Add an example to filter looping packets on (for instance) a bond
interface, by recording the egress MAC+VLAN and dropping any packets that
come in on other (related) interfaces with the same MAC+VLAN.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-05-20 14:53:14 +02:00
Toke Høiland-Jørgensen
daefd11178 encap-forward: Don't redefine AF_INET
Only conditionally define AF_INET so we don't get warnings about it being redefined.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-04-27 13:05:26 +02:00
Jesper Dangaard Brouer
3701d30083 Merge pull request #45 from xdp-project/vestas08_cleanups
Cleanups for AF_XDP-interaction code and btf_unit_test
2022-04-27 09:23:19 +02:00
Toke Høiland-Jørgensen
c673cf628f configure: Make sure libxdp is before libbpf in linker arguments
When libxdp is linked against the submodule libbpf, the order of linker
arguments is important because libxdp.a needs symbols from libbpf.a. Fix up
configure so it ensures this.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-04-27 00:43:02 +02:00
Toke Høiland-Jørgensen
c2eb81ec70 Fix xdp-tools submodule to work with libbpf submodule
Update the version of xdp-tools to pull in some configure changes that
makes interoperating between a libbpf submodule and an xdp-tools submodule
work better, and set the LIBBPF_UNBUILT variable in the top-level configure
to enables this support.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-04-26 22:03:08 +02:00
Toke Høiland-Jørgensen
6b10ae1c6e Update libbpf submodule version to v0.7.0
This version is the newest version that's compatible with xdp-tools
currently.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-04-25 18:03:00 +02:00
Jesper Dangaard Brouer
18908873a7 refactor code test02_should_fail
Introduce helper to make is easier to test two struct variations
with the same invalid btf_id struct location.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-04-22 12:21:35 +02:00
Jesper Dangaard Brouer
1e4e033c3a btf_unit_test: Add test02_should_fail
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-04-22 11:29:47 +02:00
Jesper Dangaard Brouer
7409814e44 btf_unit_test: Fix small leak
If init_btf_info_via_bpf_object() fails, then we should release bpf_object.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-04-22 10:43:55 +02:00
Jesper Dangaard Brouer
f14a20a15d btf_unit_test: Prepare partition of tests
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-04-22 10:41:27 +02:00
Jesper Dangaard Brouer
8b2494f0c0 btf_unit_test: Remember to free memory
It is a bad habit to rely on process exit to free memory.
Add proper memory free operations.

Using checker command: 
  valgrind --leak-check=yes ./btf_unit_test

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-04-22 10:34:16 +02:00
Jesper Dangaard Brouer
9ed0567cf3 btf_unit_test: Load BPF-object file btf_unit_test_bpf.o
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-04-22 10:15:05 +02:00
Jesper Dangaard Brouer
1f15e94296 btf_unit_test: Refactor load_bpf_object to take filename
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-04-22 10:12:50 +02:00
Jesper Dangaard Brouer
20916547db AF_XDP-interaction: Add BPF object/code for unit test
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-04-22 08:33:40 +02:00
Toke Høiland-Jørgensen
78b45bde56 pping: Use libxdp to load and attach XDP program
Since we now have libxdp as a submodule, we can switch pping over to using
libxdp for loading its XDP program. This requires switching the order of
attachment, because libxdp needs to be fed the BPF object in an unloaded
state (and will load it as part of attaching).

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-04-20 17:08:36 +02:00
Toke Høiland-Jørgensen
441650c510 Merge pull request #26 from xdp-project/libxdp
Embedding libxdp
2022-04-20 13:37:27 +02:00
Toke Høiland-Jørgensen
24cea38474 nat64-bpf: Use logging helpers and add verbose option
Use the newly-added logging helpers from logging.h and add a -v option to
increase the effective log level.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-04-20 13:25:27 +02:00
Toke Høiland-Jørgensen
f27c7c2c46 lib/util: Import logging helpers from xdp-tools
Include logging.{h,c} from xdp-tools so utilities can use them for setting
libxdp and libbpf logging.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-04-20 13:24:22 +02:00
Toke Høiland-Jørgensen
4d74e4aaf3 lib/xdp-tools: update version
Pull the latest version of xdp-tools into the submodule. Change the
wildcard pattern for libxdp to not include the XDP programs to avoid
constantly recompiling it.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-04-20 13:12:45 +02:00
Toke Høiland-Jørgensen
4ac5a33a40 lib: simplify installation of libbpf and libxdp submodule libraries
Instead of having the someone redundantly named 'lib/lib-install' folder,
let's rename it to just 'lib/install', and drop the 'usr/' prefix of the
files installed into that directory. Also, to simplify the configure
script, check in the directory to git so it's always present, and always
include it in the include and linker paths. On clean we just clear out the
contents.

Also, copy over libbpf.a to lib/install/lib alongside libxdp.a instead of
putting libbpf/src in the linker path.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-04-20 13:12:45 +02:00
Toke Høiland-Jørgensen
ff3e4272ff Integrate libxdp as a submodule
This adds libxdp as a submodule and link target alongside libbpf. This
should make it just as easy for examples to use libxdp as it currently is
for libbpf. Some hoops need to be jumped through to make libxdp link
against the same version of libbpf as the one we use in this repository.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-04-20 13:12:45 +02:00
Toke Høiland-Jørgensen
58fcc521b7 pping: Guard local definitions of AF_* constants in pping_kern.c
The header files included from pping_kern.c include definitions of AF_INET
and AF_INET6, leading to warnings like:

pping_kern.c:25:9: warning: 'AF_INET' macro redefined [-Wmacro-redefined]
        ^
/usr/include/bits/socket.h:97:9: note: previous definition is here
        ^
pping_kern.c:26:9: warning: 'AF_INET6' macro redefined [-Wmacro-redefined]
        ^
/usr/include/bits/socket.h:105:9: note: previous definition is here
        ^
2 warnings generated.

Fix this by guarding the definitions behind suitable ifdefs.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
2022-04-14 21:29:32 +02:00
Jesper Dangaard Brouer
a0e2c91983 AF_XDP-interaction: lib user don't need to check for btf_id
Now that lib side of xsk_btf__init_xdp_hint check for a valid
btf_id variable, then users of the call doesn't need to check
for the existance of a btf_id member.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-04-05 10:35:34 +02:00
Toke Høiland-Jørgensen
5ca0416e9e Merge pull request #43 from simosund/pping_dualdirection_flowstate
PPing dualdirection flowstate
2022-03-31 17:58:25 +02:00
Simon Sundberg
2e7595b3ca pping: Replace boolean connection state flags with enum
The connection state had 3 boolean flags related to what state it was
in (is_empty, has_opened and has_closed). Only specific combinations
of these flags really made sense (has_opened/has_closed didn't really
mean anything if is_empty, and if has_closed one would expect is_empty
to be false and has_opened to be true etc.). Therefore, replace these
combinations of boolean values with a singular enum which is used to
check if the flow is empty, waiting to open (seen outgoing packet but
no response), is open or has closed.

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-03-30 18:12:46 +02:00
Simon Sundberg
4fb1f6de64 pping: Combine flow state in each direction to a dualflow state
Combine the flow state entries for both the "forward" and "reverse"
direction of the flow into a single dualflow state. Change the
flowstate map to use the dualflow state so that state for both
directions can be retrieved using a single map lookup.

As flow states are now kept in pairs, cannot directly create/delete
states from the BPF map each time a flow opens/closes in one
direction. Therefore, update all logic related to creating/deleting
flows. For example, use "empty" slot in dualflow state instead of
creating a new map entry, and only delete the dual flow state entry
once both directions of the flow have closed/timed out.

Some implementation details:

Have implemented a simple memcmp function as I could not get the
__builtin_memcmp function to work (got error "libbpf: failed to
find BTF for extern 'memcmp': -2").

To ensure that both directions of the flow always look up the same
entry, use the "sorted" flow tuple (the (ip, port) pair that is
smaller is always first) as key. This is what the memcmp is used for.

To avoid storing two copies of the flow tuple (src -> dst and dst ->
src) and doing additional memcmps, always store the flow state for the
"sorted" direction as the first direction and the reverse as the
second direction. Then simply check if a flow is sorted or not to
determine which direction in the dual flow state that matches. Have
attempted to at least partially abstract this detail away from most of
the code by adding some get_flowstate_from* helpers.

The dual flow state simply stores the two (single direction) flow
states as the struct members dir1 and dir2. Use these two (admittedly
poorly named) members instead of a single array of size 2 in order to
avoid some issues with the verifier being worried that the array index
might be out of bounds.

Have added some new boolean members to the flow state to keep track of
"connection state". In addition the the previous has_opened, I now
also have a member for if the flow is "empty" or if it has been
closed. These are needed to cope with having to keep individual flow
states for both directions of the flow around as long as one direction
of the flow is used. I plan to replace these boolean "connection
state" members with a single enum in a future commit.

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-03-30 18:12:46 +02:00
Jesper Dangaard Brouer
871378bd4d AF_XDP-interaction: lib_xsk_extend: Validate 'btf_id' is last member
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-03-25 14:17:23 +01:00
Jesper Dangaard Brouer
7715df83ee AF_XDP-interaction: Add BTF decoding code to btf_unit_test
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-03-24 12:25:07 +01:00
Simon Sundberg
75a979fc31 pping: Refactor parsing of packet identifiers
Refactor functions for parsing protocol-specific packet
identifiers (parse_tcp_identifier, parse_icmp6_identifer and
parse_icmp_identifer) so they no longer directly fill in the
packet_info struct. Instead make the functions take additional
pointers as arguments and fill in a protocol_info struct.

The reason for this change is to decouple the
parse_<protocol>_identifier functions from the logic of how the
packet_info struct should be filled. The parse_packet_indentifier is
now solely responsible for filling in the members of packet_info
struct correctly instead of working in tandem with the
parse_<protocol>_identifier, filling in some members each.

This might result in a minimal performance degradation as some values
are now first filled in the protocol_info struct and later copied to
packet_info instead of being filled in directly in packet_info.

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-03-22 13:24:09 +01:00
Simon Sundberg
2935fb05cc pping: Minor formating fixes
Format code using clang-format from the kernel tree. However, leave
code in orginal format in some instances where clang-format clearly
reduces readability of code (ex. do not remove alginment of comments
for struct members and long options).

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-03-22 09:11:53 +01:00
Toke Høiland-Jørgensen
b7d365dcaa Merge pull request #41 from simosund/pping_ref_count
PPing optimization: Tracking outstanding timestamps
2022-03-21 15:52:06 +01:00
Jesper Dangaard Brouer
2b3fcf932d AF_XDP-interaction: Add btf_unit_test
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-03-21 15:10:46 +01:00
Jesper Dangaard Brouer
f9095c5caf AF_XDP-interaction: lib_xsk_extend: Validate 'btf_id' member MUST exist
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-03-21 13:24:26 +01:00
Jesper Dangaard Brouer
02ccbfc152 AF_XDP-interaction: Move function xsk_btf__init_xdp_hint
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
2022-03-21 12:47:56 +01:00
Simon Sundberg
8c0084dd0e pping: Update TODO about timestamp ref count
Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-03-15 15:39:53 +01:00
Simon Sundberg
11f1d88742 pping: Keep track of outstanding timestamps
Add a counter of outstanding (unmatched) timestamped entires in the
flow state. Before a timestamp lookup is attempted, check that there
are any outstanding timestamps, otherwise avoid the unecessary hash
map lookup.

Use 32 bit counter for outstanding timestamps to allow atomic
increments/decrements using __synch_fetch_and_add. This operation is
not supported on smaller integers, which is why such a large counter
is used. The atomicity is needed because the counter may be
concurrently accessed by both the ingress/egress hook as well as the
periodical map cleanup.

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-03-15 15:39:53 +01:00
Toke Høiland-Jørgensen
a6e4dd8748 Merge pull request #34 from simosund/pping_better_map_cleaning
PPing - Improve map cleanup
2022-03-10 14:28:22 +01:00
Simon Sundberg
e7201c9eab pping: Update TODO based on map cleaning improvements
Also add description of three potential issues introduced by the
changes to cleanup process.

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
2022-03-10 09:59:21 +01:00