brintos

brintos / linux-shallow public Read only

0
0
Text · 21.6 KiB · db44e77 Raw
766 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * TCP-AO selftest library. Provides helpers to unshare network4 * namespaces, create veth, assign ip addresses, set routes,5 * manipulate socket options, read network counter and etc.6 * Author: Dmitry Safonov <dima@arista.com>7 */8#ifndef _AOLIB_H_9#define _AOLIB_H_10 11#include <arpa/inet.h>12#include <errno.h>13#include <linux/snmp.h>14#include <linux/tcp.h>15#include <netinet/in.h>16#include <stdarg.h>17#include <stdbool.h>18#include <stdlib.h>19#include <stdio.h>20#include <string.h>21#include <sys/syscall.h>22#include <unistd.h>23 24#include "../../../../../include/linux/stringify.h"25#include "../../../../../include/linux/bits.h"26 27#ifndef SOL_TCP28/* can't include <netinet/tcp.h> as including <linux/tcp.h> */29# define SOL_TCP		6	/* TCP level */30#endif31 32/* Working around ksft, see the comment in lib/setup.c */33extern void __test_msg(const char *buf);34extern void __test_ok(const char *buf);35extern void __test_fail(const char *buf);36extern void __test_xfail(const char *buf);37extern void __test_error(const char *buf);38extern void __test_skip(const char *buf);39 40static inline char *test_snprintf(const char *fmt, va_list vargs)41{42	char *ret = NULL;43	size_t size = 0;44	va_list tmp;45	int n = 0;46 47	va_copy(tmp, vargs);48	n = vsnprintf(ret, size, fmt, tmp);49	if (n < 0)50		return NULL;51 52	size = n + 1;53	ret = malloc(size);54	if (!ret)55		return NULL;56 57	n = vsnprintf(ret, size, fmt, vargs);58	if (n < 0 || n > size - 1) {59		free(ret);60		return NULL;61	}62	return ret;63}64 65static __printf(1, 2) inline char *test_sprintf(const char *fmt, ...)66{67	va_list vargs;68	char *ret;69 70	va_start(vargs, fmt);71	ret = test_snprintf(fmt, vargs);72	va_end(vargs);73 74	return ret;75}76 77static __printf(2, 3) inline void __test_print(void (*fn)(const char *),78					       const char *fmt, ...)79{80	va_list vargs;81	char *msg;82 83	va_start(vargs, fmt);84	msg = test_snprintf(fmt, vargs);85	va_end(vargs);86 87	if (!msg)88		return;89 90	fn(msg);91	free(msg);92}93 94#define test_print(fmt, ...)						\95	__test_print(__test_msg, "%ld[%s:%u] " fmt "\n",		\96		     syscall(SYS_gettid),				\97		     __FILE__, __LINE__, ##__VA_ARGS__)98 99#define test_ok(fmt, ...)						\100	__test_print(__test_ok, fmt "\n", ##__VA_ARGS__)101#define test_skip(fmt, ...)						\102	__test_print(__test_skip, fmt "\n", ##__VA_ARGS__)103#define test_xfail(fmt, ...)						\104	__test_print(__test_xfail, fmt "\n", ##__VA_ARGS__)105 106#define test_fail(fmt, ...)						\107do {									\108	if (errno)							\109		__test_print(__test_fail, fmt ": %m\n", ##__VA_ARGS__);	\110	else								\111		__test_print(__test_fail, fmt "\n", ##__VA_ARGS__);	\112	test_failed();							\113} while (0)114 115#define KSFT_FAIL  1116#define test_error(fmt, ...)						\117do {									\118	if (errno)							\119		__test_print(__test_error, "%ld[%s:%u] " fmt ": %m\n",	\120			     syscall(SYS_gettid), __FILE__, __LINE__,	\121			     ##__VA_ARGS__);				\122	else								\123		__test_print(__test_error, "%ld[%s:%u] " fmt "\n",	\124			     syscall(SYS_gettid), __FILE__, __LINE__,	\125			     ##__VA_ARGS__);				\126	exit(KSFT_FAIL);						\127} while (0)128 129enum test_fault {130	FAULT_TIMEOUT = 1,131	FAULT_KEYREJECT,132	FAULT_PREINSTALL_AO,133	FAULT_PREINSTALL_MD5,134	FAULT_POSTINSTALL,135	FAULT_BUSY,136	FAULT_CURRNEXT,137	FAULT_FIXME,138};139typedef enum test_fault fault_t;140 141enum test_needs_kconfig {142	KCONFIG_NET_NS = 0,		/* required */143	KCONFIG_VETH,			/* required */144	KCONFIG_TCP_AO,			/* required */145	KCONFIG_TCP_MD5,		/* optional, for TCP-MD5 features */146	KCONFIG_NET_VRF,		/* optional, for L3/VRF testing */147	KCONFIG_FTRACE,			/* optional, for tracepoints checks */148	__KCONFIG_LAST__149};150extern bool kernel_config_has(enum test_needs_kconfig k);151extern const char *tests_skip_reason[__KCONFIG_LAST__];152static inline bool should_skip_test(const char *tst_name,153				    enum test_needs_kconfig k)154{155	if (kernel_config_has(k))156		return false;157	test_skip("%s: %s", tst_name, tests_skip_reason[k]);158	return true;159}160 161union tcp_addr {162	struct in_addr a4;163	struct in6_addr a6;164};165 166typedef void *(*thread_fn)(void *);167extern void test_failed(void);168extern void __test_init(unsigned int ntests, int family, unsigned int prefix,169			union tcp_addr addr1, union tcp_addr addr2,170			thread_fn peer1, thread_fn peer2);171 172static inline void test_init2(unsigned int ntests,173			      thread_fn peer1, thread_fn peer2,174			      int family, unsigned int prefix,175			      const char *addr1, const char *addr2)176{177	union tcp_addr taddr1, taddr2;178 179	if (inet_pton(family, addr1, &taddr1) != 1)180		test_error("Can't convert ip address %s", addr1);181	if (inet_pton(family, addr2, &taddr2) != 1)182		test_error("Can't convert ip address %s", addr2);183 184	__test_init(ntests, family, prefix, taddr1, taddr2, peer1, peer2);185}186extern void test_add_destructor(void (*d)(void));187extern void test_init_ftrace(int nsfd1, int nsfd2);188extern int test_setup_tracing(void);189 190/* To adjust optmem socket limit, approximately estimate a number,191 * that is bigger than sizeof(struct tcp_ao_key).192 */193#define KERNEL_TCP_AO_KEY_SZ_ROUND_UP	300194 195extern void test_set_optmem(size_t value);196extern size_t test_get_optmem(void);197 198extern const struct sockaddr_in6 addr_any6;199extern const struct sockaddr_in addr_any4;200 201#ifdef IPV6_TEST202# define __TEST_CLIENT_IP(n)	("2001:db8:" __stringify(n) "::1")203# define TEST_CLIENT_IP	__TEST_CLIENT_IP(1)204# define TEST_WRONG_IP	"2001:db8:253::1"205# define TEST_SERVER_IP	"2001:db8:254::1"206# define TEST_NETWORK	"2001::"207# define TEST_PREFIX	128208# define TEST_FAMILY	AF_INET6209# define SOCKADDR_ANY	addr_any6210# define sockaddr_af	struct sockaddr_in6211#else212# define __TEST_CLIENT_IP(n)	("10.0." __stringify(n) ".1")213# define TEST_CLIENT_IP	__TEST_CLIENT_IP(1)214# define TEST_WRONG_IP	"10.0.253.1"215# define TEST_SERVER_IP	"10.0.254.1"216# define TEST_NETWORK	"10.0.0.0"217# define TEST_PREFIX	32218# define TEST_FAMILY	AF_INET219# define SOCKADDR_ANY	addr_any4220# define sockaddr_af	struct sockaddr_in221#endif222 223static inline union tcp_addr gen_tcp_addr(union tcp_addr net, size_t n)224{225	union tcp_addr ret = net;226 227#ifdef IPV6_TEST228	ret.a6.s6_addr32[3] = htonl(n & (BIT(32) - 1));229	ret.a6.s6_addr32[2] = htonl((n >> 32) & (BIT(32) - 1));230#else231	ret.a4.s_addr = htonl(ntohl(net.a4.s_addr) + n);232#endif233 234	return ret;235}236 237static inline void tcp_addr_to_sockaddr_in(void *dest,238					   const union tcp_addr *src,239					   unsigned int port)240{241	sockaddr_af *out = dest;242 243	memset(out, 0, sizeof(*out));244#ifdef IPV6_TEST245	out->sin6_family = AF_INET6;246	out->sin6_port   = port;247	out->sin6_addr   = src->a6;248#else249	out->sin_family  = AF_INET;250	out->sin_port    = port;251	out->sin_addr    = src->a4;252#endif253}254 255static inline void test_init(unsigned int ntests,256			     thread_fn peer1, thread_fn peer2)257{258	test_init2(ntests, peer1, peer2, TEST_FAMILY, TEST_PREFIX,259			TEST_SERVER_IP, TEST_CLIENT_IP);260}261extern void synchronize_threads(void);262extern void switch_ns(int fd);263extern int switch_save_ns(int fd);264extern void switch_close_ns(int fd);265 266extern __thread union tcp_addr this_ip_addr;267extern __thread union tcp_addr this_ip_dest;268extern int test_family;269 270extern void randomize_buffer(void *buf, size_t buflen);271extern __printf(3, 4) int test_echo(const char *fname, bool append,272				    const char *fmt, ...);273 274extern int open_netns(void);275extern int unshare_open_netns(void);276extern const char veth_name[];277extern int add_veth(const char *name, int nsfda, int nsfdb);278extern int add_vrf(const char *name, uint32_t tabid, int ifindex, int nsfd);279extern int ip_addr_add(const char *intf, int family,280		       union tcp_addr addr, uint8_t prefix);281extern int ip_route_add(const char *intf, int family,282			union tcp_addr src, union tcp_addr dst);283extern int ip_route_add_vrf(const char *intf, int family,284			    union tcp_addr src, union tcp_addr dst,285			    uint8_t vrf);286extern int link_set_up(const char *intf);287 288extern const unsigned int test_server_port;289extern int test_wait_fd(int sk, time_t sec, bool write);290extern int __test_connect_socket(int sk, const char *device,291				 void *addr, size_t addr_sz, time_t timeout);292extern int __test_listen_socket(int backlog, void *addr, size_t addr_sz);293 294static inline int test_listen_socket(const union tcp_addr taddr,295				     unsigned int port, int backlog)296{297	sockaddr_af addr;298 299	tcp_addr_to_sockaddr_in(&addr, &taddr, htons(port));300	return __test_listen_socket(backlog, (void *)&addr, sizeof(addr));301}302 303/*304 * In order for selftests to work under CONFIG_CRYPTO_FIPS=y,305 * the password should be loger than 14 bytes, see hmac_setkey()306 */307#define TEST_TCP_AO_MINKEYLEN	14308#define DEFAULT_TEST_PASSWORD	"In this hour, I do not believe that any darkness will endure."309 310#ifndef DEFAULT_TEST_ALGO311#define DEFAULT_TEST_ALGO	"cmac(aes128)"312#endif313 314#ifdef IPV6_TEST315#define DEFAULT_TEST_PREFIX	128316#else317#define DEFAULT_TEST_PREFIX	32318#endif319 320/*321 * Timeout on syscalls where failure is not expected.322 * You may want to rise it if the test machine is very busy.323 */324#ifndef TEST_TIMEOUT_SEC325#define TEST_TIMEOUT_SEC	5326#endif327 328/*329 * Timeout on connect() where a failure is expected.330 * If set to 0 - kernel will try to retransmit SYN number of times, set in331 * /proc/sys/net/ipv4/tcp_syn_retries332 * By default set to 1 to make tests pass faster on non-busy machine.333 */334#ifndef TEST_RETRANSMIT_SEC335#define TEST_RETRANSMIT_SEC	1336#endif337 338static inline int _test_connect_socket(int sk, const union tcp_addr taddr,339				       unsigned int port, time_t timeout)340{341	sockaddr_af addr;342 343	tcp_addr_to_sockaddr_in(&addr, &taddr, htons(port));344	return __test_connect_socket(sk, veth_name,345				     (void *)&addr, sizeof(addr), timeout);346}347 348static inline int test_connect_socket(int sk, const union tcp_addr taddr,349				      unsigned int port)350{351	return _test_connect_socket(sk, taddr, port, TEST_TIMEOUT_SEC);352}353 354extern int __test_set_md5(int sk, void *addr, size_t addr_sz,355			  uint8_t prefix, int vrf, const char *password);356static inline int test_set_md5(int sk, const union tcp_addr in_addr,357			       uint8_t prefix, int vrf, const char *password)358{359	sockaddr_af addr;360 361	if (prefix > DEFAULT_TEST_PREFIX)362		prefix = DEFAULT_TEST_PREFIX;363 364	tcp_addr_to_sockaddr_in(&addr, &in_addr, 0);365	return __test_set_md5(sk, (void *)&addr, sizeof(addr),366			prefix, vrf, password);367}368 369extern int test_prepare_key_sockaddr(struct tcp_ao_add *ao, const char *alg,370		void *addr, size_t addr_sz, bool set_current, bool set_rnext,371		uint8_t prefix, uint8_t vrf,372		uint8_t sndid, uint8_t rcvid, uint8_t maclen,373		uint8_t keyflags, uint8_t keylen, const char *key);374 375static inline int test_prepare_key(struct tcp_ao_add *ao,376		const char *alg, union tcp_addr taddr,377		bool set_current, bool set_rnext,378		uint8_t prefix, uint8_t vrf,379		uint8_t sndid, uint8_t rcvid, uint8_t maclen,380		uint8_t keyflags, uint8_t keylen, const char *key)381{382	sockaddr_af addr;383 384	tcp_addr_to_sockaddr_in(&addr, &taddr, 0);385	return test_prepare_key_sockaddr(ao, alg, (void *)&addr, sizeof(addr),386			set_current, set_rnext, prefix, vrf, sndid, rcvid,387			maclen, keyflags, keylen, key);388}389 390static inline int test_prepare_def_key(struct tcp_ao_add *ao,391		const char *key, uint8_t keyflags,392		union tcp_addr in_addr, uint8_t prefix, uint8_t vrf,393		uint8_t sndid, uint8_t rcvid)394{395	if (prefix > DEFAULT_TEST_PREFIX)396		prefix = DEFAULT_TEST_PREFIX;397 398	return test_prepare_key(ao, DEFAULT_TEST_ALGO, in_addr, false, false,399				prefix, vrf, sndid, rcvid, 0, keyflags,400				strlen(key), key);401}402 403extern int test_get_one_ao(int sk, struct tcp_ao_getsockopt *out,404			   void *addr, size_t addr_sz,405			   uint8_t prefix, uint8_t sndid, uint8_t rcvid);406extern int test_get_ao_info(int sk, struct tcp_ao_info_opt *out);407extern int test_set_ao_info(int sk, struct tcp_ao_info_opt *in);408extern int test_cmp_getsockopt_setsockopt(const struct tcp_ao_add *a,409					  const struct tcp_ao_getsockopt *b);410extern int test_cmp_getsockopt_setsockopt_ao(const struct tcp_ao_info_opt *a,411					     const struct tcp_ao_info_opt *b);412 413static inline int test_verify_socket_key(int sk, struct tcp_ao_add *key)414{415	struct tcp_ao_getsockopt key2 = {};416	int err;417 418	err = test_get_one_ao(sk, &key2, &key->addr, sizeof(key->addr),419			      key->prefix, key->sndid, key->rcvid);420	if (err)421		return err;422 423	return test_cmp_getsockopt_setsockopt(key, &key2);424}425 426static inline int test_add_key_vrf(int sk,427				   const char *key, uint8_t keyflags,428				   union tcp_addr in_addr, uint8_t prefix,429				   uint8_t vrf, uint8_t sndid, uint8_t rcvid)430{431	struct tcp_ao_add tmp = {};432	int err;433 434	err = test_prepare_def_key(&tmp, key, keyflags, in_addr, prefix,435				   vrf, sndid, rcvid);436	if (err)437		return err;438 439	err = setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp));440	if (err < 0)441		return -errno;442 443	return test_verify_socket_key(sk, &tmp);444}445 446static inline int test_add_key(int sk, const char *key,447			      union tcp_addr in_addr, uint8_t prefix,448			      uint8_t sndid, uint8_t rcvid)449{450	return test_add_key_vrf(sk, key, 0, in_addr, prefix, 0, sndid, rcvid);451}452 453static inline int test_verify_socket_ao(int sk, struct tcp_ao_info_opt *ao)454{455	struct tcp_ao_info_opt ao2 = {};456	int err;457 458	err = test_get_ao_info(sk, &ao2);459	if (err)460		return err;461 462	return test_cmp_getsockopt_setsockopt_ao(ao, &ao2);463}464 465static inline int test_set_ao_flags(int sk, bool ao_required, bool accept_icmps)466{467	struct tcp_ao_info_opt ao = {};468	int err;469 470	err = test_get_ao_info(sk, &ao);471	/* Maybe ao_info wasn't allocated yet */472	if (err && err != -ENOENT)473		return err;474 475	ao.ao_required = !!ao_required;476	ao.accept_icmps = !!accept_icmps;477	err = test_set_ao_info(sk, &ao);478	if (err)479		return err;480 481	return test_verify_socket_ao(sk, &ao);482}483 484extern ssize_t test_server_run(int sk, ssize_t quota, time_t timeout_sec);485extern ssize_t test_client_loop(int sk, char *buf, size_t buf_sz,486				const size_t msg_len, time_t timeout_sec);487extern int test_client_verify(int sk, const size_t msg_len, const size_t nr,488			      time_t timeout_sec);489 490struct tcp_ao_key_counters {491	uint8_t sndid;492	uint8_t rcvid;493	uint64_t pkt_good;494	uint64_t pkt_bad;495};496 497struct tcp_ao_counters {498	/* per-netns */499	uint64_t netns_ao_good;500	uint64_t netns_ao_bad;501	uint64_t netns_ao_key_not_found;502	uint64_t netns_ao_required;503	uint64_t netns_ao_dropped_icmp;504	/* per-socket */505	uint64_t ao_info_pkt_good;506	uint64_t ao_info_pkt_bad;507	uint64_t ao_info_pkt_key_not_found;508	uint64_t ao_info_pkt_ao_required;509	uint64_t ao_info_pkt_dropped_icmp;510	/* per-key */511	size_t nr_keys;512	struct tcp_ao_key_counters *key_cnts;513};514extern int test_get_tcp_ao_counters(int sk, struct tcp_ao_counters *out);515 516#define TEST_CNT_KEY_GOOD		BIT(0)517#define TEST_CNT_KEY_BAD		BIT(1)518#define TEST_CNT_SOCK_GOOD		BIT(2)519#define TEST_CNT_SOCK_BAD		BIT(3)520#define TEST_CNT_SOCK_KEY_NOT_FOUND	BIT(4)521#define TEST_CNT_SOCK_AO_REQUIRED	BIT(5)522#define TEST_CNT_SOCK_DROPPED_ICMP	BIT(6)523#define TEST_CNT_NS_GOOD		BIT(7)524#define TEST_CNT_NS_BAD			BIT(8)525#define TEST_CNT_NS_KEY_NOT_FOUND	BIT(9)526#define TEST_CNT_NS_AO_REQUIRED		BIT(10)527#define TEST_CNT_NS_DROPPED_ICMP	BIT(11)528typedef uint16_t test_cnt;529 530#define TEST_CNT_AO_GOOD		(TEST_CNT_SOCK_GOOD | TEST_CNT_NS_GOOD)531#define TEST_CNT_AO_BAD			(TEST_CNT_SOCK_BAD | TEST_CNT_NS_BAD)532#define TEST_CNT_AO_KEY_NOT_FOUND	(TEST_CNT_SOCK_KEY_NOT_FOUND | \533					 TEST_CNT_NS_KEY_NOT_FOUND)534#define TEST_CNT_AO_REQUIRED		(TEST_CNT_SOCK_AO_REQUIRED | \535					 TEST_CNT_NS_AO_REQUIRED)536#define TEST_CNT_AO_DROPPED_ICMP	(TEST_CNT_SOCK_DROPPED_ICMP | \537					 TEST_CNT_NS_DROPPED_ICMP)538#define TEST_CNT_GOOD			(TEST_CNT_KEY_GOOD | TEST_CNT_AO_GOOD)539#define TEST_CNT_BAD			(TEST_CNT_KEY_BAD | TEST_CNT_AO_BAD)540 541extern int __test_tcp_ao_counters_cmp(const char *tst_name,542		struct tcp_ao_counters *before, struct tcp_ao_counters *after,543		test_cnt expected);544extern int test_tcp_ao_key_counters_cmp(const char *tst_name,545		struct tcp_ao_counters *before, struct tcp_ao_counters *after,546		test_cnt expected, int sndid, int rcvid);547extern void test_tcp_ao_counters_free(struct tcp_ao_counters *cnts);548/*549 * Frees buffers allocated in test_get_tcp_ao_counters().550 * The function doesn't expect new keys or keys removed between calls551 * to test_get_tcp_ao_counters(). Check key counters manually if they552 * may change.553 */554static inline int test_tcp_ao_counters_cmp(const char *tst_name,555					   struct tcp_ao_counters *before,556					   struct tcp_ao_counters *after,557					   test_cnt expected)558{559	int ret;560 561	ret = __test_tcp_ao_counters_cmp(tst_name, before, after, expected);562	if (ret)563		goto out;564	ret = test_tcp_ao_key_counters_cmp(tst_name, before, after,565					   expected, -1, -1);566out:567	test_tcp_ao_counters_free(before);568	test_tcp_ao_counters_free(after);569	return ret;570}571 572struct netstat;573extern struct netstat *netstat_read(void);574extern void netstat_free(struct netstat *ns);575extern void netstat_print_diff(struct netstat *nsa, struct netstat *nsb);576extern uint64_t netstat_get(struct netstat *ns,577			    const char *name, bool *not_found);578 579static inline uint64_t netstat_get_one(const char *name, bool *not_found)580{581	struct netstat *ns = netstat_read();582	uint64_t ret;583 584	ret = netstat_get(ns, name, not_found);585 586	netstat_free(ns);587	return ret;588}589 590struct tcp_sock_queue {591	uint32_t seq;592	void *buf;593};594 595struct tcp_sock_state {596	struct tcp_info info;597	struct tcp_repair_window trw;598	struct tcp_sock_queue out;599	int outq_len;		/* output queue size (not sent + not acked) */600	int outq_nsd_len;	/* output queue size (not sent only) */601	struct tcp_sock_queue in;602	int inq_len;603	int mss;604	int timestamp;605};606 607extern void __test_sock_checkpoint(int sk, struct tcp_sock_state *state,608				   void *addr, size_t addr_size);609static inline void test_sock_checkpoint(int sk, struct tcp_sock_state *state,610					sockaddr_af *saddr)611{612	__test_sock_checkpoint(sk, state, saddr, sizeof(*saddr));613}614extern void test_ao_checkpoint(int sk, struct tcp_ao_repair *state);615extern void __test_sock_restore(int sk, const char *device,616				struct tcp_sock_state *state,617				void *saddr, void *daddr, size_t addr_size);618static inline void test_sock_restore(int sk, struct tcp_sock_state *state,619				     sockaddr_af *saddr,620				     const union tcp_addr daddr,621				     unsigned int dport)622{623	sockaddr_af addr;624 625	tcp_addr_to_sockaddr_in(&addr, &daddr, htons(dport));626	__test_sock_restore(sk, veth_name, state, saddr, &addr, sizeof(addr));627}628extern void test_ao_restore(int sk, struct tcp_ao_repair *state);629extern void test_sock_state_free(struct tcp_sock_state *state);630extern void test_enable_repair(int sk);631extern void test_disable_repair(int sk);632extern void test_kill_sk(int sk);633static inline int test_add_repaired_key(int sk,634					const char *key, uint8_t keyflags,635					union tcp_addr in_addr, uint8_t prefix,636					uint8_t sndid, uint8_t rcvid)637{638	struct tcp_ao_add tmp = {};639	int err;640 641	err = test_prepare_def_key(&tmp, key, keyflags, in_addr, prefix,642				   0, sndid, rcvid);643	if (err)644		return err;645 646	tmp.set_current = 1;647	tmp.set_rnext = 1;648	if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp)) < 0)649		return -errno;650 651	return test_verify_socket_key(sk, &tmp);652}653 654#define DEFAULT_FTRACE_BUFFER_KB	10000655#define DEFAULT_TRACER_LINES_ARR	200656struct test_ftracer;657extern uint64_t ns_cookie1, ns_cookie2;658 659enum ftracer_op {660	FTRACER_LINE_DISCARD = 0,661	FTRACER_LINE_PRESERVE,662	FTRACER_EXIT,663};664 665extern struct test_ftracer *create_ftracer(const char *name,666		enum ftracer_op (*process_line)(const char *line),667		void (*destructor)(struct test_ftracer *tracer),668		bool (*expecting_more)(void),669		size_t lines_buf_sz, size_t buffer_size_kb);670extern int setup_trace_event(struct test_ftracer *tracer,671			     const char *event, const char *filter);672extern void destroy_ftracer(struct test_ftracer *tracer);673extern const size_t tracer_get_savedlines_nr(struct test_ftracer *tracer);674extern const char **tracer_get_savedlines(struct test_ftracer *tracer);675 676enum trace_events {677	/* TCP_HASH_EVENT */678	TCP_HASH_BAD_HEADER = 0,679	TCP_HASH_MD5_REQUIRED,680	TCP_HASH_MD5_UNEXPECTED,681	TCP_HASH_MD5_MISMATCH,682	TCP_HASH_AO_REQUIRED,683	/* TCP_AO_EVENT */684	TCP_AO_HANDSHAKE_FAILURE,685	TCP_AO_WRONG_MACLEN,686	TCP_AO_MISMATCH,687	TCP_AO_KEY_NOT_FOUND,688	TCP_AO_RNEXT_REQUEST,689	/* TCP_AO_EVENT_SK */690	TCP_AO_SYNACK_NO_KEY,691	/* TCP_AO_EVENT_SNE */692	TCP_AO_SND_SNE_UPDATE,693	TCP_AO_RCV_SNE_UPDATE,694	__MAX_TRACE_EVENTS695};696 697extern int __trace_event_expect(enum trace_events type, int family,698				union tcp_addr src, union tcp_addr dst,699				int src_port, int dst_port, int L3index,700				int fin, int syn, int rst, int psh, int ack,701				int keyid, int rnext, int maclen, int sne);702 703static inline void trace_hash_event_expect(enum trace_events type,704				union tcp_addr src, union tcp_addr dst,705				int src_port, int dst_port, int L3index,706				int fin, int syn, int rst, int psh, int ack)707{708	int err;709 710	err = __trace_event_expect(type, TEST_FAMILY, src, dst,711				   src_port, dst_port, L3index,712				   fin, syn, rst, psh, ack,713				   -1, -1, -1, -1);714	if (err)715		test_error("Couldn't add a trace event: %d", err);716}717 718static inline void trace_ao_event_expect(enum trace_events type,719				union tcp_addr src, union tcp_addr dst,720				int src_port, int dst_port, int L3index,721				int fin, int syn, int rst, int psh, int ack,722				int keyid, int rnext, int maclen)723{724	int err;725 726	err = __trace_event_expect(type, TEST_FAMILY, src, dst,727				   src_port, dst_port, L3index,728				   fin, syn, rst, psh, ack,729				   keyid, rnext, maclen, -1);730	if (err)731		test_error("Couldn't add a trace event: %d", err);732}733 734static inline void trace_ao_event_sk_expect(enum trace_events type,735				union tcp_addr src, union tcp_addr dst,736				int src_port, int dst_port,737				int keyid, int rnext)738{739	int err;740 741	err = __trace_event_expect(type, TEST_FAMILY, src, dst,742				   src_port, dst_port, -1,743				   -1, -1, -1, -1, -1,744				   keyid, rnext, -1, -1);745	if (err)746		test_error("Couldn't add a trace event: %d", err);747}748 749static inline void trace_ao_event_sne_expect(enum trace_events type,750				union tcp_addr src, union tcp_addr dst,751				int src_port, int dst_port, int sne)752{753	int err;754 755	err = __trace_event_expect(type, TEST_FAMILY, src, dst,756				   src_port, dst_port, -1,757				   -1, -1, -1, -1, -1,758				   -1, -1, -1, sne);759	if (err)760		test_error("Couldn't add a trace event: %d", err);761}762 763extern int setup_aolib_ftracer(void);764 765#endif /* _AOLIB_H_ */766