cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tcp_rtt.c (3434B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <test_progs.h>
      3#include "cgroup_helpers.h"
      4#include "network_helpers.h"
      5#include "tcp_rtt.skel.h"
      6
      7struct tcp_rtt_storage {
      8	__u32 invoked;
      9	__u32 dsack_dups;
     10	__u32 delivered;
     11	__u32 delivered_ce;
     12	__u32 icsk_retransmits;
     13};
     14
     15static void send_byte(int fd)
     16{
     17	char b = 0x55;
     18
     19	if (CHECK_FAIL(write(fd, &b, sizeof(b)) != 1))
     20		perror("Failed to send single byte");
     21}
     22
     23static int wait_for_ack(int fd, int retries)
     24{
     25	struct tcp_info info;
     26	socklen_t optlen;
     27	int i, err;
     28
     29	for (i = 0; i < retries; i++) {
     30		optlen = sizeof(info);
     31		err = getsockopt(fd, SOL_TCP, TCP_INFO, &info, &optlen);
     32		if (err < 0) {
     33			log_err("Failed to lookup TCP stats");
     34			return err;
     35		}
     36
     37		if (info.tcpi_unacked == 0)
     38			return 0;
     39
     40		usleep(10);
     41	}
     42
     43	log_err("Did not receive ACK");
     44	return -1;
     45}
     46
     47static int verify_sk(int map_fd, int client_fd, const char *msg, __u32 invoked,
     48		     __u32 dsack_dups, __u32 delivered, __u32 delivered_ce,
     49		     __u32 icsk_retransmits)
     50{
     51	int err = 0;
     52	struct tcp_rtt_storage val;
     53
     54	if (CHECK_FAIL(bpf_map_lookup_elem(map_fd, &client_fd, &val) < 0)) {
     55		perror("Failed to read socket storage");
     56		return -1;
     57	}
     58
     59	if (val.invoked != invoked) {
     60		log_err("%s: unexpected bpf_tcp_sock.invoked %d != %d",
     61			msg, val.invoked, invoked);
     62		err++;
     63	}
     64
     65	if (val.dsack_dups != dsack_dups) {
     66		log_err("%s: unexpected bpf_tcp_sock.dsack_dups %d != %d",
     67			msg, val.dsack_dups, dsack_dups);
     68		err++;
     69	}
     70
     71	if (val.delivered != delivered) {
     72		log_err("%s: unexpected bpf_tcp_sock.delivered %d != %d",
     73			msg, val.delivered, delivered);
     74		err++;
     75	}
     76
     77	if (val.delivered_ce != delivered_ce) {
     78		log_err("%s: unexpected bpf_tcp_sock.delivered_ce %d != %d",
     79			msg, val.delivered_ce, delivered_ce);
     80		err++;
     81	}
     82
     83	if (val.icsk_retransmits != icsk_retransmits) {
     84		log_err("%s: unexpected bpf_tcp_sock.icsk_retransmits %d != %d",
     85			msg, val.icsk_retransmits, icsk_retransmits);
     86		err++;
     87	}
     88
     89	return err;
     90}
     91
     92
     93static int run_test(int cgroup_fd, int server_fd)
     94{
     95	struct tcp_rtt *skel;
     96	int client_fd;
     97	int prog_fd;
     98	int map_fd;
     99	int err;
    100
    101	skel = tcp_rtt__open_and_load();
    102	if (!ASSERT_OK_PTR(skel, "skel_open_load"))
    103		return -1;
    104
    105	map_fd = bpf_map__fd(skel->maps.socket_storage_map);
    106	prog_fd = bpf_program__fd(skel->progs._sockops);
    107
    108	err = bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS, 0);
    109	if (err) {
    110		log_err("Failed to attach BPF program");
    111		goto close_bpf_object;
    112	}
    113
    114	client_fd = connect_to_fd(server_fd, 0);
    115	if (client_fd < 0) {
    116		err = -1;
    117		goto close_bpf_object;
    118	}
    119
    120	err += verify_sk(map_fd, client_fd, "syn-ack",
    121			 /*invoked=*/1,
    122			 /*dsack_dups=*/0,
    123			 /*delivered=*/1,
    124			 /*delivered_ce=*/0,
    125			 /*icsk_retransmits=*/0);
    126
    127	send_byte(client_fd);
    128	if (wait_for_ack(client_fd, 100) < 0) {
    129		err = -1;
    130		goto close_client_fd;
    131	}
    132
    133
    134	err += verify_sk(map_fd, client_fd, "first payload byte",
    135			 /*invoked=*/2,
    136			 /*dsack_dups=*/0,
    137			 /*delivered=*/2,
    138			 /*delivered_ce=*/0,
    139			 /*icsk_retransmits=*/0);
    140
    141close_client_fd:
    142	close(client_fd);
    143
    144close_bpf_object:
    145	tcp_rtt__destroy(skel);
    146	return err;
    147}
    148
    149void test_tcp_rtt(void)
    150{
    151	int server_fd, cgroup_fd;
    152
    153	cgroup_fd = test__join_cgroup("/tcp_rtt");
    154	if (CHECK_FAIL(cgroup_fd < 0))
    155		return;
    156
    157	server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 0, 0);
    158	if (CHECK_FAIL(server_fd < 0))
    159		goto close_cgroup_fd;
    160
    161	CHECK_FAIL(run_test(cgroup_fd, server_fd));
    162
    163	close(server_fd);
    164
    165close_cgroup_fd:
    166	close(cgroup_fd);
    167}