// SPDX-License-Identifier: GPL-2.0
/* Author: Dmitry Safonov <dima@arista.com> */
#include <inttypes.h>
#include "../../../../include/linux/kernel.h"
#include "aolib.h"
const size_t nr_packets = 20;
const size_t msg_len = 100;
const size_t quota = nr_packets * msg_len;
union tcp_addr wrong_addr;
#define SECOND_PASSWORD "at all times sincere friends of freedom have been rare"
#define fault(type) (inj == FAULT_ ## type)
static const int test_vrf_ifindex = 200;
static const uint8_t test_vrf_tabid = 42;
static void setup_vrfs(void)
{
int err;
if (!kernel_config_has(KCONFIG_NET_VRF))
return;
err = add_vrf("ksft-vrf", test_vrf_tabid, test_vrf_ifindex, -1);
if (err)
test_error("Failed to add a VRF: %d", err);
err = link_set_up("ksft-vrf");
if (err)
test_error("Failed to bring up a VRF");
err = ip_route_add_vrf(veth_name, TEST_FAMILY,
this_ip_addr, this_ip_dest, test_vrf_tabid);
if (err)
test_error("Failed to add a route to VRF");
}
static int prepare_sk(union tcp_addr *addr, uint8_t sndid, uint8_t rcvid)
{
int sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
if (sk < 0)
test_error("socket()");
if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest,
DEFAULT_TEST_PREFIX, 100, 100))
test_error("test_add_key()");
if (addr && test_add_key(sk, SECOND_PASSWORD, *addr,
DEFAULT_TEST_PREFIX, sndid, rcvid))
test_error("test_add_key()");
return sk;
}
static int prepare_lsk(union tcp_addr *addr, uint8_t sndid, uint8_t rcvid)
{
int sk = prepare_sk(addr, sndid, rcvid);
if (listen(sk, 10))
test_error("listen()");
return sk;
}
static int test_del_key(int sk, uint8_t sndid, uint8_t rcvid, bool async,
int current_key, int rnext_key)
{
struct tcp_ao_info_opt ao_info = {};
struct tcp_ao_getsockopt key = {};
struct tcp_ao_del del = {};
sockaddr_af sockaddr;
int err;
tcp_addr_to_sockaddr_in(&del.addr, &this_ip_dest, 0);
del.prefix = DEFAULT_TEST_PREFIX;
del.sndid = sndid;
del.rcvid = rcvid;
if (current_key >= 0) {
del.set_current = 1;
del.current_key = (uint8_t)current_key;
}
if (rnext_key >= 0) {
del.set_rnext = 1;
del.rnext = (uint8_t)rnext_key;
}
err = setsockopt(sk, IPPROTO_TCP, TCP_AO_DEL_KEY, &del, sizeof(del));
if (err < 0)
return -errno;
if (async)
return 0;
tcp_addr_to_sockaddr_in(&sockaddr, &this_ip_dest, 0);
err = test_get_one_ao(sk, &key, &sockaddr, sizeof(sockaddr),
DEFAULT_TEST_PREFIX, sndid, rcvid);
if (!err)
return -EEXIST;
if (err != -E2BIG)
test_error("getsockopt()");
if (current_key < 0 && rnext_key < 0)
return 0;
if (test_get_ao_info(sk, &ao_info))
test_error("getsockopt(TCP_AO_INFO) failed");
if (current_key >= 0 && ao_info.current_key != (uint8_t)current_key)
return -ENOTRECOVERABLE;
if (rnext_key >= 0 && ao_info.rnext != (uint8_t)rnext_key)
return -ENOTRECOVERABLE;
return 0;
}