Skip to content

Commit

Permalink
selftests/net: Add trace events matching to tcp_ao
Browse files Browse the repository at this point in the history
Setup trace points, add a new ftrace instance in order to not interfere
with the rest of the system, filtering by net namespace cookies.
Raise a new background thread that parses trace_pipe, matches them with
the list of expected events.

Wiring up trace events to selftests provides another insight if there is
anything unexpected happining in the tcp-ao code (i.e. key rotation when
it's not expected).

Note: in real programs libtraceevent should be used instead of this
manual labor of setting ftrace up and parsing. I'm not using it here
as I don't want to have an .so library dependency that one would have to
bring into VM or DUT (Device Under Test). Please, don't copy it over
into any real world programs, that aren't tests.

Signed-off-by: Dmitry Safonov <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
0x7f454c46 authored and kuba-moo committed Aug 27, 2024
1 parent 044e037 commit 586d870
Show file tree
Hide file tree
Showing 19 changed files with 1,358 additions and 18 deletions.
3 changes: 2 additions & 1 deletion tools/testing/selftests/net/tcp_ao/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ CFLAGS += $(KHDR_INCLUDES)
CFLAGS += -iquote ./lib/ -I ../../../../include/

# Library
LIBSRC := kconfig.c netlink.c proc.c repair.c setup.c sock.c utils.c
LIBSRC := ftrace.c ftrace-tcp.c kconfig.c netlink.c
LIBSRC += proc.c repair.c setup.c sock.c utils.c
LIBOBJ := $(LIBSRC:%.c=$(LIBDIR)/%.o)
EXTRA_CLEAN += $(LIBOBJ) $(LIB)

Expand Down
2 changes: 1 addition & 1 deletion tools/testing/selftests/net/tcp_ao/bench-lookups.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,6 @@ static void *client_fn(void *arg)

int main(int argc, char *argv[])
{
test_init(30, server_fn, client_fn);
test_init(31, server_fn, client_fn);
return 0;
}
1 change: 1 addition & 0 deletions tools/testing/selftests/net/tcp_ao/config
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ CONFIG_NET_L3_MASTER_DEV=y
CONFIG_NET_VRF=y
CONFIG_TCP_AO=y
CONFIG_TCP_MD5SIG=y
CONFIG_TRACEPOINTS=y
CONFIG_VETH=m
18 changes: 16 additions & 2 deletions tools/testing/selftests/net/tcp_ao/connect-deny.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,30 +215,44 @@ static void try_connect(const char *tst_name, unsigned int port,

static void *client_fn(void *arg)
{
union tcp_addr wrong_addr, network_addr;
union tcp_addr wrong_addr, network_addr, addr_any = {};
unsigned int port = test_server_port;

if (inet_pton(TEST_FAMILY, TEST_WRONG_IP, &wrong_addr) != 1)
test_error("Can't convert ip address %s", TEST_WRONG_IP);

trace_ao_event_expect(TCP_AO_KEY_NOT_FOUND, this_ip_addr, this_ip_dest,
-1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1);
try_connect("Non-AO server + AO client", port++, DEFAULT_TEST_PASSWORD,
this_ip_dest, -1, 100, 100, 0, FAULT_TIMEOUT);

trace_hash_event_expect(TCP_HASH_AO_REQUIRED, this_ip_addr, this_ip_dest,
-1, port, 0, 0, 1, 0, 0, 0);
try_connect("AO server + Non-AO client", port++, NULL,
this_ip_dest, -1, 100, 100, 0, FAULT_TIMEOUT);

trace_ao_event_expect(TCP_AO_MISMATCH, this_ip_addr, this_ip_dest,
-1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1);
try_connect("Wrong password", port++, DEFAULT_TEST_PASSWORD,
this_ip_dest, -1, 100, 100, 0, FAULT_TIMEOUT);

trace_ao_event_expect(TCP_AO_KEY_NOT_FOUND, this_ip_addr, this_ip_dest,
-1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1);
try_connect("Wrong rcv id", port++, DEFAULT_TEST_PASSWORD,
this_ip_dest, -1, 100, 100, 0, FAULT_TIMEOUT);

trace_ao_event_sk_expect(TCP_AO_SYNACK_NO_KEY, this_ip_dest, addr_any,
port, 0, 100, 100);
try_connect("Wrong snd id", port++, DEFAULT_TEST_PASSWORD,
this_ip_dest, -1, 100, 100, 0, FAULT_TIMEOUT);

trace_ao_event_expect(TCP_AO_WRONG_MACLEN, this_ip_addr, this_ip_dest,
-1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1);
try_connect("Different maclen", port++, DEFAULT_TEST_PASSWORD,
this_ip_dest, -1, 100, 100, 0, FAULT_TIMEOUT);

trace_ao_event_expect(TCP_AO_KEY_NOT_FOUND, this_ip_addr, this_ip_dest,
-1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1);
try_connect("Server: Wrong addr", port++, DEFAULT_TEST_PASSWORD,
this_ip_dest, -1, 100, 100, 0, FAULT_TIMEOUT);

Expand All @@ -262,6 +276,6 @@ static void *client_fn(void *arg)

int main(int argc, char *argv[])
{
test_init(21, server_fn, client_fn);
test_init(22, server_fn, client_fn);
return 0;
}
2 changes: 1 addition & 1 deletion tools/testing/selftests/net/tcp_ao/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@ static void *client_fn(void *arg)

int main(int argc, char *argv[])
{
test_init(1, server_fn, client_fn);
test_init(2, server_fn, client_fn);
return 0;
}
2 changes: 1 addition & 1 deletion tools/testing/selftests/net/tcp_ao/icmps-discard.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,6 @@ static void *client_fn(void *arg)

int main(int argc, char *argv[])
{
test_init(3, server_fn, client_fn);
test_init(4, server_fn, client_fn);
return 0;
}
18 changes: 15 additions & 3 deletions tools/testing/selftests/net/tcp_ao/key-management.c
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ static void end_client(const char *tst_name, int sk, unsigned int nr_keys,
synchronize_threads(); /* 5: counters */
}

static void try_unmatched_keys(int sk, int *rnext_index)
static void try_unmatched_keys(int sk, int *rnext_index, unsigned int port)
{
struct test_key *key;
unsigned int i = 0;
Expand Down Expand Up @@ -1013,6 +1013,9 @@ static void try_unmatched_keys(int sk, int *rnext_index)
test_error("all keys on server match the client");
if (test_set_key(sk, -1, key->server_keyid))
test_error("Can't change the current key");
trace_ao_event_expect(TCP_AO_RNEXT_REQUEST, this_ip_addr, this_ip_dest,
-1, port, 0, -1, -1, -1, -1, -1,
-1, key->server_keyid, -1);
if (test_client_verify(sk, msg_len, nr_packets, TEST_TIMEOUT_SEC))
test_fail("verify failed");
*rnext_index = i;
Expand Down Expand Up @@ -1054,6 +1057,10 @@ static void check_current_back(const char *tst_name, unsigned int port,
return;
if (test_set_key(sk, collection.keys[rotate_to_index].client_keyid, -1))
test_error("Can't change the current key");
trace_ao_event_expect(TCP_AO_RNEXT_REQUEST, this_ip_dest, this_ip_addr,
port, -1, 0, -1, -1, -1, -1, -1,
collection.keys[rotate_to_index].client_keyid,
collection.keys[current_index].client_keyid, -1);
if (test_client_verify(sk, msg_len, nr_packets, TEST_TIMEOUT_SEC))
test_fail("verify failed");
/* There is a race here: between setting the current_key with
Expand Down Expand Up @@ -1085,6 +1092,11 @@ static void roll_over_keys(const char *tst_name, unsigned int port,
for (i = rnext_index + 1; rotations > 0; i++, rotations--) {
if (i >= collection.nr_keys)
i = 0;
trace_ao_event_expect(TCP_AO_RNEXT_REQUEST,
this_ip_addr, this_ip_dest,
-1, port, 0, -1, -1, -1, -1, -1,
i == 0 ? -1 : collection.keys[i - 1].server_keyid,
collection.keys[i].server_keyid, -1);
if (test_set_key(sk, -1, collection.keys[i].server_keyid))
test_error("Can't change the Rnext key");
if (test_client_verify(sk, msg_len, nr_packets, TEST_TIMEOUT_SEC)) {
Expand Down Expand Up @@ -1124,7 +1136,7 @@ static void try_client_match(const char *tst_name, unsigned int port,
rnext_index, msg_len, nr_packets);
if (sk < 0)
return;
try_unmatched_keys(sk, &rnext_index);
try_unmatched_keys(sk, &rnext_index, port);
end_client(tst_name, sk, nr_keys, current_index, rnext_index, NULL);
}

Expand Down Expand Up @@ -1181,6 +1193,6 @@ static void *client_fn(void *arg)

int main(int argc, char *argv[])
{
test_init(120, server_fn, client_fn);
test_init(121, server_fn, client_fn);
return 0;
}
119 changes: 119 additions & 0 deletions tools/testing/selftests/net/tcp_ao/lib/aolib.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ enum test_needs_kconfig {
KCONFIG_TCP_AO, /* required */
KCONFIG_TCP_MD5, /* optional, for TCP-MD5 features */
KCONFIG_NET_VRF, /* optional, for L3/VRF testing */
KCONFIG_FTRACE, /* optional, for tracepoints checks */
__KCONFIG_LAST__
};
extern bool kernel_config_has(enum test_needs_kconfig k);
Expand Down Expand Up @@ -183,6 +184,8 @@ static inline void test_init2(unsigned int ntests,
__test_init(ntests, family, prefix, taddr1, taddr2, peer1, peer2);
}
extern void test_add_destructor(void (*d)(void));
extern void test_init_ftrace(int nsfd1, int nsfd2);
extern int test_setup_tracing(void);

/* To adjust optmem socket limit, approximately estimate a number,
* that is bigger than sizeof(struct tcp_ao_key).
Expand Down Expand Up @@ -257,12 +260,17 @@ static inline void test_init(unsigned int ntests,
}
extern void synchronize_threads(void);
extern void switch_ns(int fd);
extern int switch_save_ns(int fd);
extern void switch_close_ns(int fd);

extern __thread union tcp_addr this_ip_addr;
extern __thread union tcp_addr this_ip_dest;
extern int test_family;

extern void randomize_buffer(void *buf, size_t buflen);
extern __printf(3, 4) int test_echo(const char *fname, bool append,
const char *fmt, ...);

extern int open_netns(void);
extern int unshare_open_netns(void);
extern const char veth_name[];
Expand Down Expand Up @@ -643,4 +651,115 @@ static inline int test_add_repaired_key(int sk,
return test_verify_socket_key(sk, &tmp);
}

#define DEFAULT_FTRACE_BUFFER_KB 10000
#define DEFAULT_TRACER_LINES_ARR 200
struct test_ftracer;
extern uint64_t ns_cookie1, ns_cookie2;

enum ftracer_op {
FTRACER_LINE_DISCARD = 0,
FTRACER_LINE_PRESERVE,
FTRACER_EXIT,
};

extern struct test_ftracer *create_ftracer(const char *name,
enum ftracer_op (*process_line)(const char *line),
void (*destructor)(struct test_ftracer *tracer),
bool (*expecting_more)(void),
size_t lines_buf_sz, size_t buffer_size_kb);
extern int setup_trace_event(struct test_ftracer *tracer,
const char *event, const char *filter);
extern void destroy_ftracer(struct test_ftracer *tracer);
extern const size_t tracer_get_savedlines_nr(struct test_ftracer *tracer);
extern const char **tracer_get_savedlines(struct test_ftracer *tracer);

enum trace_events {
/* TCP_HASH_EVENT */
TCP_HASH_BAD_HEADER = 0,
TCP_HASH_MD5_REQUIRED,
TCP_HASH_MD5_UNEXPECTED,
TCP_HASH_MD5_MISMATCH,
TCP_HASH_AO_REQUIRED,
/* TCP_AO_EVENT */
TCP_AO_HANDSHAKE_FAILURE,
TCP_AO_WRONG_MACLEN,
TCP_AO_MISMATCH,
TCP_AO_KEY_NOT_FOUND,
TCP_AO_RNEXT_REQUEST,
/* TCP_AO_EVENT_SK */
TCP_AO_SYNACK_NO_KEY,
/* TCP_AO_EVENT_SNE */
TCP_AO_SND_SNE_UPDATE,
TCP_AO_RCV_SNE_UPDATE,
__MAX_TRACE_EVENTS
};

extern int __trace_event_expect(enum trace_events type, int family,
union tcp_addr src, union tcp_addr dst,
int src_port, int dst_port, int L3index,
int fin, int syn, int rst, int psh, int ack,
int keyid, int rnext, int maclen, int sne);

static inline void trace_hash_event_expect(enum trace_events type,
union tcp_addr src, union tcp_addr dst,
int src_port, int dst_port, int L3index,
int fin, int syn, int rst, int psh, int ack)
{
int err;

err = __trace_event_expect(type, TEST_FAMILY, src, dst,
src_port, dst_port, L3index,
fin, syn, rst, psh, ack,
-1, -1, -1, -1);
if (err)
test_error("Couldn't add a trace event: %d", err);
}

static inline void trace_ao_event_expect(enum trace_events type,
union tcp_addr src, union tcp_addr dst,
int src_port, int dst_port, int L3index,
int fin, int syn, int rst, int psh, int ack,
int keyid, int rnext, int maclen)
{
int err;

err = __trace_event_expect(type, TEST_FAMILY, src, dst,
src_port, dst_port, L3index,
fin, syn, rst, psh, ack,
keyid, rnext, maclen, -1);
if (err)
test_error("Couldn't add a trace event: %d", err);
}

static inline void trace_ao_event_sk_expect(enum trace_events type,
union tcp_addr src, union tcp_addr dst,
int src_port, int dst_port,
int keyid, int rnext)
{
int err;

err = __trace_event_expect(type, TEST_FAMILY, src, dst,
src_port, dst_port, -1,
-1, -1, -1, -1, -1,
keyid, rnext, -1, -1);
if (err)
test_error("Couldn't add a trace event: %d", err);
}

static inline void trace_ao_event_sne_expect(enum trace_events type,
union tcp_addr src, union tcp_addr dst,
int src_port, int dst_port, int sne)
{
int err;

err = __trace_event_expect(type, TEST_FAMILY, src, dst,
src_port, dst_port, -1,
-1, -1, -1, -1, -1,
-1, -1, -1, sne);
if (err)
test_error("Couldn't add a trace event: %d", err);
}

extern int setup_aolib_ftracer(void);

#endif /* _AOLIB_H_ */
Loading

0 comments on commit 586d870

Please sign in to comment.