brintos

brintos / linux-shallow public Read only

0
0
Text · 54.9 KiB · be4a30a Raw
2342 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * ipsec.c - Check xfrm on veth inside a net-ns.4 * Copyright (c) 2018 Dmitry Safonov5 */6 7#define _GNU_SOURCE8 9#include <arpa/inet.h>10#include <asm/types.h>11#include <errno.h>12#include <fcntl.h>13#include <limits.h>14#include <linux/limits.h>15#include <linux/netlink.h>16#include <linux/random.h>17#include <linux/rtnetlink.h>18#include <linux/veth.h>19#include <linux/xfrm.h>20#include <netinet/in.h>21#include <net/if.h>22#include <sched.h>23#include <stdbool.h>24#include <stdint.h>25#include <stdio.h>26#include <stdlib.h>27#include <string.h>28#include <sys/mman.h>29#include <sys/socket.h>30#include <sys/stat.h>31#include <sys/syscall.h>32#include <sys/types.h>33#include <sys/wait.h>34#include <time.h>35#include <unistd.h>36 37#include "../kselftest.h"38 39#define printk(fmt, ...)						\40	ksft_print_msg("%d[%u] " fmt "\n", getpid(), __LINE__, ##__VA_ARGS__)41 42#define pr_err(fmt, ...)	printk(fmt ": %m", ##__VA_ARGS__)43 44#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))45 46#define IPV4_STR_SZ	16	/* xxx.xxx.xxx.xxx is longest + \0 */47#define MAX_PAYLOAD	204848#define XFRM_ALGO_KEY_BUF_SIZE	51249#define MAX_PROCESSES	(1 << 14) /* /16 mask divided by /30 subnets */50#define INADDR_A	((in_addr_t) 0x0a000000) /* 10.0.0.0 */51#define INADDR_B	((in_addr_t) 0xc0a80000) /* 192.168.0.0 */52 53/* /30 mask for one veth connection */54#define PREFIX_LEN	3055#define child_ip(nr)	(4*nr + 1)56#define grchild_ip(nr)	(4*nr + 2)57 58#define VETH_FMT	"ktst-%d"59#define VETH_LEN	1260 61#define XFRM_ALGO_NR_KEYS 2962 63static int nsfd_parent	= -1;64static int nsfd_childa	= -1;65static int nsfd_childb	= -1;66static long page_size;67 68/*69 * ksft_cnt is static in kselftest, so isn't shared with children.70 * We have to send a test result back to parent and count there.71 * results_fd is a pipe with test feedback from children.72 */73static int results_fd[2];74 75const unsigned int ping_delay_nsec	= 50 * 1000 * 1000;76const unsigned int ping_timeout		= 300;77const unsigned int ping_count		= 100;78const unsigned int ping_success		= 80;79 80struct xfrm_key_entry {81	char algo_name[35];82	int key_len;83};84 85struct xfrm_key_entry xfrm_key_entries[] = {86	{"digest_null", 0},87	{"ecb(cipher_null)", 0},88	{"cbc(des)", 64},89	{"hmac(md5)", 128},90	{"cmac(aes)", 128},91	{"xcbc(aes)", 128},92	{"cbc(cast5)", 128},93	{"cbc(serpent)", 128},94	{"hmac(sha1)", 160},95	{"hmac(rmd160)", 160},96	{"cbc(des3_ede)", 192},97	{"hmac(sha256)", 256},98	{"cbc(aes)", 256},99	{"cbc(camellia)", 256},100	{"cbc(twofish)", 256},101	{"rfc3686(ctr(aes))", 288},102	{"hmac(sha384)", 384},103	{"cbc(blowfish)", 448},104	{"hmac(sha512)", 512},105	{"rfc4106(gcm(aes))-128", 160},106	{"rfc4543(gcm(aes))-128", 160},107	{"rfc4309(ccm(aes))-128", 152},108	{"rfc4106(gcm(aes))-192", 224},109	{"rfc4543(gcm(aes))-192", 224},110	{"rfc4309(ccm(aes))-192", 216},111	{"rfc4106(gcm(aes))-256", 288},112	{"rfc4543(gcm(aes))-256", 288},113	{"rfc4309(ccm(aes))-256", 280},114	{"rfc7539(chacha20,poly1305)-128", 0}115};116 117static void randomize_buffer(void *buf, size_t buflen)118{119	int *p = (int *)buf;120	size_t words = buflen / sizeof(int);121	size_t leftover = buflen % sizeof(int);122 123	if (!buflen)124		return;125 126	while (words--)127		*p++ = rand();128 129	if (leftover) {130		int tmp = rand();131 132		memcpy(buf + buflen - leftover, &tmp, leftover);133	}134 135	return;136}137 138static int unshare_open(void)139{140	const char *netns_path = "/proc/self/ns/net";141	int fd;142 143	if (unshare(CLONE_NEWNET) != 0) {144		pr_err("unshare()");145		return -1;146	}147 148	fd = open(netns_path, O_RDONLY);149	if (fd <= 0) {150		pr_err("open(%s)", netns_path);151		return -1;152	}153 154	return fd;155}156 157static int switch_ns(int fd)158{159	if (setns(fd, CLONE_NEWNET)) {160		pr_err("setns()");161		return -1;162	}163	return 0;164}165 166/*167 * Running the test inside a new parent net namespace to bother less168 * about cleanup on error-path.169 */170static int init_namespaces(void)171{172	nsfd_parent = unshare_open();173	if (nsfd_parent <= 0)174		return -1;175 176	nsfd_childa = unshare_open();177	if (nsfd_childa <= 0)178		return -1;179 180	if (switch_ns(nsfd_parent))181		return -1;182 183	nsfd_childb = unshare_open();184	if (nsfd_childb <= 0)185		return -1;186 187	if (switch_ns(nsfd_parent))188		return -1;189	return 0;190}191 192static int netlink_sock(int *sock, uint32_t *seq_nr, int proto)193{194	if (*sock > 0) {195		seq_nr++;196		return 0;197	}198 199	*sock = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, proto);200	if (*sock <= 0) {201		pr_err("socket(AF_NETLINK)");202		return -1;203	}204 205	randomize_buffer(seq_nr, sizeof(*seq_nr));206 207	return 0;208}209 210static inline struct rtattr *rtattr_hdr(struct nlmsghdr *nh)211{212	return (struct rtattr *)((char *)(nh) + RTA_ALIGN((nh)->nlmsg_len));213}214 215static int rtattr_pack(struct nlmsghdr *nh, size_t req_sz,216		unsigned short rta_type, const void *payload, size_t size)217{218	/* NLMSG_ALIGNTO == RTA_ALIGNTO, nlmsg_len already aligned */219	struct rtattr *attr = rtattr_hdr(nh);220	size_t nl_size = RTA_ALIGN(nh->nlmsg_len) + RTA_LENGTH(size);221 222	if (req_sz < nl_size) {223		printk("req buf is too small: %zu < %zu", req_sz, nl_size);224		return -1;225	}226	nh->nlmsg_len = nl_size;227 228	attr->rta_len = RTA_LENGTH(size);229	attr->rta_type = rta_type;230	memcpy(RTA_DATA(attr), payload, size);231 232	return 0;233}234 235static struct rtattr *_rtattr_begin(struct nlmsghdr *nh, size_t req_sz,236		unsigned short rta_type, const void *payload, size_t size)237{238	struct rtattr *ret = rtattr_hdr(nh);239 240	if (rtattr_pack(nh, req_sz, rta_type, payload, size))241		return 0;242 243	return ret;244}245 246static inline struct rtattr *rtattr_begin(struct nlmsghdr *nh, size_t req_sz,247		unsigned short rta_type)248{249	return _rtattr_begin(nh, req_sz, rta_type, 0, 0);250}251 252static inline void rtattr_end(struct nlmsghdr *nh, struct rtattr *attr)253{254	char *nlmsg_end = (char *)nh + nh->nlmsg_len;255 256	attr->rta_len = nlmsg_end - (char *)attr;257}258 259static int veth_pack_peerb(struct nlmsghdr *nh, size_t req_sz,260		const char *peer, int ns)261{262	struct ifinfomsg pi;263	struct rtattr *peer_attr;264 265	memset(&pi, 0, sizeof(pi));266	pi.ifi_family	= AF_UNSPEC;267	pi.ifi_change	= 0xFFFFFFFF;268 269	peer_attr = _rtattr_begin(nh, req_sz, VETH_INFO_PEER, &pi, sizeof(pi));270	if (!peer_attr)271		return -1;272 273	if (rtattr_pack(nh, req_sz, IFLA_IFNAME, peer, strlen(peer)))274		return -1;275 276	if (rtattr_pack(nh, req_sz, IFLA_NET_NS_FD, &ns, sizeof(ns)))277		return -1;278 279	rtattr_end(nh, peer_attr);280 281	return 0;282}283 284static int netlink_check_answer(int sock)285{286	struct nlmsgerror {287		struct nlmsghdr hdr;288		int error;289		struct nlmsghdr orig_msg;290	} answer;291 292	if (recv(sock, &answer, sizeof(answer), 0) < 0) {293		pr_err("recv()");294		return -1;295	} else if (answer.hdr.nlmsg_type != NLMSG_ERROR) {296		printk("expected NLMSG_ERROR, got %d", (int)answer.hdr.nlmsg_type);297		return -1;298	} else if (answer.error) {299		printk("NLMSG_ERROR: %d: %s",300			answer.error, strerror(-answer.error));301		return answer.error;302	}303 304	return 0;305}306 307static int veth_add(int sock, uint32_t seq, const char *peera, int ns_a,308		const char *peerb, int ns_b)309{310	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;311	struct {312		struct nlmsghdr		nh;313		struct ifinfomsg	info;314		char			attrbuf[MAX_PAYLOAD];315	} req;316	const char veth_type[] = "veth";317	struct rtattr *link_info, *info_data;318 319	memset(&req, 0, sizeof(req));320	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.info));321	req.nh.nlmsg_type	= RTM_NEWLINK;322	req.nh.nlmsg_flags	= flags;323	req.nh.nlmsg_seq	= seq;324	req.info.ifi_family	= AF_UNSPEC;325	req.info.ifi_change	= 0xFFFFFFFF;326 327	if (rtattr_pack(&req.nh, sizeof(req), IFLA_IFNAME, peera, strlen(peera)))328		return -1;329 330	if (rtattr_pack(&req.nh, sizeof(req), IFLA_NET_NS_FD, &ns_a, sizeof(ns_a)))331		return -1;332 333	link_info = rtattr_begin(&req.nh, sizeof(req), IFLA_LINKINFO);334	if (!link_info)335		return -1;336 337	if (rtattr_pack(&req.nh, sizeof(req), IFLA_INFO_KIND, veth_type, sizeof(veth_type)))338		return -1;339 340	info_data = rtattr_begin(&req.nh, sizeof(req), IFLA_INFO_DATA);341	if (!info_data)342		return -1;343 344	if (veth_pack_peerb(&req.nh, sizeof(req), peerb, ns_b))345		return -1;346 347	rtattr_end(&req.nh, info_data);348	rtattr_end(&req.nh, link_info);349 350	if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {351		pr_err("send()");352		return -1;353	}354	return netlink_check_answer(sock);355}356 357static int ip4_addr_set(int sock, uint32_t seq, const char *intf,358		struct in_addr addr, uint8_t prefix)359{360	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;361	struct {362		struct nlmsghdr		nh;363		struct ifaddrmsg	info;364		char			attrbuf[MAX_PAYLOAD];365	} req;366 367	memset(&req, 0, sizeof(req));368	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.info));369	req.nh.nlmsg_type	= RTM_NEWADDR;370	req.nh.nlmsg_flags	= flags;371	req.nh.nlmsg_seq	= seq;372	req.info.ifa_family	= AF_INET;373	req.info.ifa_prefixlen	= prefix;374	req.info.ifa_index	= if_nametoindex(intf);375 376#ifdef DEBUG377	{378		char addr_str[IPV4_STR_SZ] = {};379 380		strncpy(addr_str, inet_ntoa(addr), IPV4_STR_SZ - 1);381 382		printk("ip addr set %s", addr_str);383	}384#endif385 386	if (rtattr_pack(&req.nh, sizeof(req), IFA_LOCAL, &addr, sizeof(addr)))387		return -1;388 389	if (rtattr_pack(&req.nh, sizeof(req), IFA_ADDRESS, &addr, sizeof(addr)))390		return -1;391 392	if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {393		pr_err("send()");394		return -1;395	}396	return netlink_check_answer(sock);397}398 399static int link_set_up(int sock, uint32_t seq, const char *intf)400{401	struct {402		struct nlmsghdr		nh;403		struct ifinfomsg	info;404		char			attrbuf[MAX_PAYLOAD];405	} req;406 407	memset(&req, 0, sizeof(req));408	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.info));409	req.nh.nlmsg_type	= RTM_NEWLINK;410	req.nh.nlmsg_flags	= NLM_F_REQUEST | NLM_F_ACK;411	req.nh.nlmsg_seq	= seq;412	req.info.ifi_family	= AF_UNSPEC;413	req.info.ifi_change	= 0xFFFFFFFF;414	req.info.ifi_index	= if_nametoindex(intf);415	req.info.ifi_flags	= IFF_UP;416	req.info.ifi_change	= IFF_UP;417 418	if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {419		pr_err("send()");420		return -1;421	}422	return netlink_check_answer(sock);423}424 425static int ip4_route_set(int sock, uint32_t seq, const char *intf,426		struct in_addr src, struct in_addr dst)427{428	struct {429		struct nlmsghdr	nh;430		struct rtmsg	rt;431		char		attrbuf[MAX_PAYLOAD];432	} req;433	unsigned int index = if_nametoindex(intf);434 435	memset(&req, 0, sizeof(req));436	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.rt));437	req.nh.nlmsg_type	= RTM_NEWROUTE;438	req.nh.nlmsg_flags	= NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE;439	req.nh.nlmsg_seq	= seq;440	req.rt.rtm_family	= AF_INET;441	req.rt.rtm_dst_len	= 32;442	req.rt.rtm_table	= RT_TABLE_MAIN;443	req.rt.rtm_protocol	= RTPROT_BOOT;444	req.rt.rtm_scope	= RT_SCOPE_LINK;445	req.rt.rtm_type		= RTN_UNICAST;446 447	if (rtattr_pack(&req.nh, sizeof(req), RTA_DST, &dst, sizeof(dst)))448		return -1;449 450	if (rtattr_pack(&req.nh, sizeof(req), RTA_PREFSRC, &src, sizeof(src)))451		return -1;452 453	if (rtattr_pack(&req.nh, sizeof(req), RTA_OIF, &index, sizeof(index)))454		return -1;455 456	if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {457		pr_err("send()");458		return -1;459	}460 461	return netlink_check_answer(sock);462}463 464static int tunnel_set_route(int route_sock, uint32_t *route_seq, char *veth,465		struct in_addr tunsrc, struct in_addr tundst)466{467	if (ip4_addr_set(route_sock, (*route_seq)++, "lo",468			tunsrc, PREFIX_LEN)) {469		printk("Failed to set ipv4 addr");470		return -1;471	}472 473	if (ip4_route_set(route_sock, (*route_seq)++, veth, tunsrc, tundst)) {474		printk("Failed to set ipv4 route");475		return -1;476	}477 478	return 0;479}480 481static int init_child(int nsfd, char *veth, unsigned int src, unsigned int dst)482{483	struct in_addr intsrc = inet_makeaddr(INADDR_B, src);484	struct in_addr tunsrc = inet_makeaddr(INADDR_A, src);485	struct in_addr tundst = inet_makeaddr(INADDR_A, dst);486	int route_sock = -1, ret = -1;487	uint32_t route_seq;488 489	if (switch_ns(nsfd))490		return -1;491 492	if (netlink_sock(&route_sock, &route_seq, NETLINK_ROUTE)) {493		printk("Failed to open netlink route socket in child");494		return -1;495	}496 497	if (ip4_addr_set(route_sock, route_seq++, veth, intsrc, PREFIX_LEN)) {498		printk("Failed to set ipv4 addr");499		goto err;500	}501 502	if (link_set_up(route_sock, route_seq++, veth)) {503		printk("Failed to bring up %s", veth);504		goto err;505	}506 507	if (tunnel_set_route(route_sock, &route_seq, veth, tunsrc, tundst)) {508		printk("Failed to add tunnel route on %s", veth);509		goto err;510	}511	ret = 0;512 513err:514	close(route_sock);515	return ret;516}517 518#define ALGO_LEN	64519enum desc_type {520	CREATE_TUNNEL	= 0,521	ALLOCATE_SPI,522	MONITOR_ACQUIRE,523	EXPIRE_STATE,524	EXPIRE_POLICY,525	SPDINFO_ATTRS,526};527const char *desc_name[] = {528	"create tunnel",529	"alloc spi",530	"monitor acquire",531	"expire state",532	"expire policy",533	"spdinfo attributes",534	""535};536struct xfrm_desc {537	enum desc_type	type;538	uint8_t		proto;539	char		a_algo[ALGO_LEN];540	char		e_algo[ALGO_LEN];541	char		c_algo[ALGO_LEN];542	char		ae_algo[ALGO_LEN];543	unsigned int	icv_len;544	/* unsigned key_len; */545};546 547enum msg_type {548	MSG_ACK		= 0,549	MSG_EXIT,550	MSG_PING,551	MSG_XFRM_PREPARE,552	MSG_XFRM_ADD,553	MSG_XFRM_DEL,554	MSG_XFRM_CLEANUP,555};556 557struct test_desc {558	enum msg_type type;559	union {560		struct {561			in_addr_t reply_ip;562			unsigned int port;563		} ping;564		struct xfrm_desc xfrm_desc;565	} body;566};567 568struct test_result {569	struct xfrm_desc desc;570	unsigned int res;571};572 573static void write_test_result(unsigned int res, struct xfrm_desc *d)574{575	struct test_result tr = {};576	ssize_t ret;577 578	tr.desc = *d;579	tr.res = res;580 581	ret = write(results_fd[1], &tr, sizeof(tr));582	if (ret != sizeof(tr))583		pr_err("Failed to write the result in pipe %zd", ret);584}585 586static void write_msg(int fd, struct test_desc *msg, bool exit_of_fail)587{588	ssize_t bytes = write(fd, msg, sizeof(*msg));589 590	/* Make sure that write/read is atomic to a pipe */591	BUILD_BUG_ON(sizeof(struct test_desc) > PIPE_BUF);592 593	if (bytes < 0) {594		pr_err("write()");595		if (exit_of_fail)596			exit(KSFT_FAIL);597	}598	if (bytes != sizeof(*msg)) {599		pr_err("sent part of the message %zd/%zu", bytes, sizeof(*msg));600		if (exit_of_fail)601			exit(KSFT_FAIL);602	}603}604 605static void read_msg(int fd, struct test_desc *msg, bool exit_of_fail)606{607	ssize_t bytes = read(fd, msg, sizeof(*msg));608 609	if (bytes < 0) {610		pr_err("read()");611		if (exit_of_fail)612			exit(KSFT_FAIL);613	}614	if (bytes != sizeof(*msg)) {615		pr_err("got incomplete message %zd/%zu", bytes, sizeof(*msg));616		if (exit_of_fail)617			exit(KSFT_FAIL);618	}619}620 621static int udp_ping_init(struct in_addr listen_ip, unsigned int u_timeout,622		unsigned int *server_port, int sock[2])623{624	struct sockaddr_in server;625	struct timeval t = { .tv_sec = 0, .tv_usec = u_timeout };626	socklen_t s_len = sizeof(server);627 628	sock[0] = socket(AF_INET, SOCK_DGRAM, 0);629	if (sock[0] < 0) {630		pr_err("socket()");631		return -1;632	}633 634	server.sin_family	= AF_INET;635	server.sin_port		= 0;636	memcpy(&server.sin_addr.s_addr, &listen_ip, sizeof(struct in_addr));637 638	if (bind(sock[0], (struct sockaddr *)&server, s_len)) {639		pr_err("bind()");640		goto err_close_server;641	}642 643	if (getsockname(sock[0], (struct sockaddr *)&server, &s_len)) {644		pr_err("getsockname()");645		goto err_close_server;646	}647 648	*server_port = ntohs(server.sin_port);649 650	if (setsockopt(sock[0], SOL_SOCKET, SO_RCVTIMEO, (const char *)&t, sizeof t)) {651		pr_err("setsockopt()");652		goto err_close_server;653	}654 655	sock[1] = socket(AF_INET, SOCK_DGRAM, 0);656	if (sock[1] < 0) {657		pr_err("socket()");658		goto err_close_server;659	}660 661	return 0;662 663err_close_server:664	close(sock[0]);665	return -1;666}667 668static int udp_ping_send(int sock[2], in_addr_t dest_ip, unsigned int port,669		char *buf, size_t buf_len)670{671	struct sockaddr_in server;672	const struct sockaddr *dest_addr = (struct sockaddr *)&server;673	char *sock_buf[buf_len];674	ssize_t r_bytes, s_bytes;675 676	server.sin_family	= AF_INET;677	server.sin_port		= htons(port);678	server.sin_addr.s_addr	= dest_ip;679 680	s_bytes = sendto(sock[1], buf, buf_len, 0, dest_addr, sizeof(server));681	if (s_bytes < 0) {682		pr_err("sendto()");683		return -1;684	} else if (s_bytes != buf_len) {685		printk("send part of the message: %zd/%zu", s_bytes, sizeof(server));686		return -1;687	}688 689	r_bytes = recv(sock[0], sock_buf, buf_len, 0);690	if (r_bytes < 0) {691		if (errno != EAGAIN)692			pr_err("recv()");693		return -1;694	} else if (r_bytes == 0) { /* EOF */695		printk("EOF on reply to ping");696		return -1;697	} else if (r_bytes != buf_len || memcmp(buf, sock_buf, buf_len)) {698		printk("ping reply packet is corrupted %zd/%zu", r_bytes, buf_len);699		return -1;700	}701 702	return 0;703}704 705static int udp_ping_reply(int sock[2], in_addr_t dest_ip, unsigned int port,706		char *buf, size_t buf_len)707{708	struct sockaddr_in server;709	const struct sockaddr *dest_addr = (struct sockaddr *)&server;710	char *sock_buf[buf_len];711	ssize_t r_bytes, s_bytes;712 713	server.sin_family	= AF_INET;714	server.sin_port		= htons(port);715	server.sin_addr.s_addr	= dest_ip;716 717	r_bytes = recv(sock[0], sock_buf, buf_len, 0);718	if (r_bytes < 0) {719		if (errno != EAGAIN)720			pr_err("recv()");721		return -1;722	}723	if (r_bytes == 0) { /* EOF */724		printk("EOF on reply to ping");725		return -1;726	}727	if (r_bytes != buf_len || memcmp(buf, sock_buf, buf_len)) {728		printk("ping reply packet is corrupted %zd/%zu", r_bytes, buf_len);729		return -1;730	}731 732	s_bytes = sendto(sock[1], buf, buf_len, 0, dest_addr, sizeof(server));733	if (s_bytes < 0) {734		pr_err("sendto()");735		return -1;736	} else if (s_bytes != buf_len) {737		printk("send part of the message: %zd/%zu", s_bytes, sizeof(server));738		return -1;739	}740 741	return 0;742}743 744typedef int (*ping_f)(int sock[2], in_addr_t dest_ip, unsigned int port,745		char *buf, size_t buf_len);746static int do_ping(int cmd_fd, char *buf, size_t buf_len, struct in_addr from,747		bool init_side, int d_port, in_addr_t to, ping_f func)748{749	struct test_desc msg;750	unsigned int s_port, i, ping_succeeded = 0;751	int ping_sock[2];752	char to_str[IPV4_STR_SZ] = {}, from_str[IPV4_STR_SZ] = {};753 754	if (udp_ping_init(from, ping_timeout, &s_port, ping_sock)) {755		printk("Failed to init ping");756		return -1;757	}758 759	memset(&msg, 0, sizeof(msg));760	msg.type		= MSG_PING;761	msg.body.ping.port	= s_port;762	memcpy(&msg.body.ping.reply_ip, &from, sizeof(from));763 764	write_msg(cmd_fd, &msg, 0);765	if (init_side) {766		/* The other end sends ip to ping */767		read_msg(cmd_fd, &msg, 0);768		if (msg.type != MSG_PING)769			return -1;770		to = msg.body.ping.reply_ip;771		d_port = msg.body.ping.port;772	}773 774	for (i = 0; i < ping_count ; i++) {775		struct timespec sleep_time = {776			.tv_sec = 0,777			.tv_nsec = ping_delay_nsec,778		};779 780		ping_succeeded += !func(ping_sock, to, d_port, buf, page_size);781		nanosleep(&sleep_time, 0);782	}783 784	close(ping_sock[0]);785	close(ping_sock[1]);786 787	strncpy(to_str, inet_ntoa(*(struct in_addr *)&to), IPV4_STR_SZ - 1);788	strncpy(from_str, inet_ntoa(from), IPV4_STR_SZ - 1);789 790	if (ping_succeeded < ping_success) {791		printk("ping (%s) %s->%s failed %u/%u times",792			init_side ? "send" : "reply", from_str, to_str,793			ping_count - ping_succeeded, ping_count);794		return -1;795	}796 797#ifdef DEBUG798	printk("ping (%s) %s->%s succeeded %u/%u times",799		init_side ? "send" : "reply", from_str, to_str,800		ping_succeeded, ping_count);801#endif802 803	return 0;804}805 806static int xfrm_fill_key(char *name, char *buf,807		size_t buf_len, unsigned int *key_len)808{809	int i;810 811	for (i = 0; i < XFRM_ALGO_NR_KEYS; i++) {812		if (strncmp(name, xfrm_key_entries[i].algo_name, ALGO_LEN) == 0)813			*key_len = xfrm_key_entries[i].key_len;814	}815 816	if (*key_len > buf_len) {817		printk("Can't pack a key - too big for buffer");818		return -1;819	}820 821	randomize_buffer(buf, *key_len);822 823	return 0;824}825 826static int xfrm_state_pack_algo(struct nlmsghdr *nh, size_t req_sz,827		struct xfrm_desc *desc)828{829	struct {830		union {831			struct xfrm_algo	alg;832			struct xfrm_algo_aead	aead;833			struct xfrm_algo_auth	auth;834		} u;835		char buf[XFRM_ALGO_KEY_BUF_SIZE];836	} alg = {};837	size_t alen, elen, clen, aelen;838	unsigned short type;839 840	alen = strlen(desc->a_algo);841	elen = strlen(desc->e_algo);842	clen = strlen(desc->c_algo);843	aelen = strlen(desc->ae_algo);844 845	/* Verify desc */846	switch (desc->proto) {847	case IPPROTO_AH:848		if (!alen || elen || clen || aelen) {849			printk("BUG: buggy ah desc");850			return -1;851		}852		strncpy(alg.u.alg.alg_name, desc->a_algo, ALGO_LEN - 1);853		if (xfrm_fill_key(desc->a_algo, alg.u.alg.alg_key,854				sizeof(alg.buf), &alg.u.alg.alg_key_len))855			return -1;856		type = XFRMA_ALG_AUTH;857		break;858	case IPPROTO_COMP:859		if (!clen || elen || alen || aelen) {860			printk("BUG: buggy comp desc");861			return -1;862		}863		strncpy(alg.u.alg.alg_name, desc->c_algo, ALGO_LEN - 1);864		if (xfrm_fill_key(desc->c_algo, alg.u.alg.alg_key,865				sizeof(alg.buf), &alg.u.alg.alg_key_len))866			return -1;867		type = XFRMA_ALG_COMP;868		break;869	case IPPROTO_ESP:870		if (!((alen && elen) ^ aelen) || clen) {871			printk("BUG: buggy esp desc");872			return -1;873		}874		if (aelen) {875			alg.u.aead.alg_icv_len = desc->icv_len;876			strncpy(alg.u.aead.alg_name, desc->ae_algo, ALGO_LEN - 1);877			if (xfrm_fill_key(desc->ae_algo, alg.u.aead.alg_key,878						sizeof(alg.buf), &alg.u.aead.alg_key_len))879				return -1;880			type = XFRMA_ALG_AEAD;881		} else {882 883			strncpy(alg.u.alg.alg_name, desc->e_algo, ALGO_LEN - 1);884			type = XFRMA_ALG_CRYPT;885			if (xfrm_fill_key(desc->e_algo, alg.u.alg.alg_key,886						sizeof(alg.buf), &alg.u.alg.alg_key_len))887				return -1;888			if (rtattr_pack(nh, req_sz, type, &alg, sizeof(alg)))889				return -1;890 891			strncpy(alg.u.alg.alg_name, desc->a_algo, ALGO_LEN);892			type = XFRMA_ALG_AUTH;893			if (xfrm_fill_key(desc->a_algo, alg.u.alg.alg_key,894						sizeof(alg.buf), &alg.u.alg.alg_key_len))895				return -1;896		}897		break;898	default:899		printk("BUG: unknown proto in desc");900		return -1;901	}902 903	if (rtattr_pack(nh, req_sz, type, &alg, sizeof(alg)))904		return -1;905 906	return 0;907}908 909static inline uint32_t gen_spi(struct in_addr src)910{911	return htonl(inet_lnaof(src));912}913 914static int xfrm_state_add(int xfrm_sock, uint32_t seq, uint32_t spi,915		struct in_addr src, struct in_addr dst,916		struct xfrm_desc *desc)917{918	struct {919		struct nlmsghdr		nh;920		struct xfrm_usersa_info	info;921		char			attrbuf[MAX_PAYLOAD];922	} req;923 924	memset(&req, 0, sizeof(req));925	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.info));926	req.nh.nlmsg_type	= XFRM_MSG_NEWSA;927	req.nh.nlmsg_flags	= NLM_F_REQUEST | NLM_F_ACK;928	req.nh.nlmsg_seq	= seq;929 930	/* Fill selector. */931	memcpy(&req.info.sel.daddr, &dst, sizeof(dst));932	memcpy(&req.info.sel.saddr, &src, sizeof(src));933	req.info.sel.family		= AF_INET;934	req.info.sel.prefixlen_d	= PREFIX_LEN;935	req.info.sel.prefixlen_s	= PREFIX_LEN;936 937	/* Fill id */938	memcpy(&req.info.id.daddr, &dst, sizeof(dst));939	/* Note: zero-spi cannot be deleted */940	req.info.id.spi = spi;941	req.info.id.proto	= desc->proto;942 943	memcpy(&req.info.saddr, &src, sizeof(src));944 945	/* Fill lifteme_cfg */946	req.info.lft.soft_byte_limit	= XFRM_INF;947	req.info.lft.hard_byte_limit	= XFRM_INF;948	req.info.lft.soft_packet_limit	= XFRM_INF;949	req.info.lft.hard_packet_limit	= XFRM_INF;950 951	req.info.family		= AF_INET;952	req.info.mode		= XFRM_MODE_TUNNEL;953 954	if (xfrm_state_pack_algo(&req.nh, sizeof(req), desc))955		return -1;956 957	if (send(xfrm_sock, &req, req.nh.nlmsg_len, 0) < 0) {958		pr_err("send()");959		return -1;960	}961 962	return netlink_check_answer(xfrm_sock);963}964 965static bool xfrm_usersa_found(struct xfrm_usersa_info *info, uint32_t spi,966		struct in_addr src, struct in_addr dst,967		struct xfrm_desc *desc)968{969	if (memcmp(&info->sel.daddr, &dst, sizeof(dst)))970		return false;971 972	if (memcmp(&info->sel.saddr, &src, sizeof(src)))973		return false;974 975	if (info->sel.family != AF_INET					||976			info->sel.prefixlen_d != PREFIX_LEN		||977			info->sel.prefixlen_s != PREFIX_LEN)978		return false;979 980	if (info->id.spi != spi || info->id.proto != desc->proto)981		return false;982 983	if (memcmp(&info->id.daddr, &dst, sizeof(dst)))984		return false;985 986	if (memcmp(&info->saddr, &src, sizeof(src)))987		return false;988 989	if (info->lft.soft_byte_limit != XFRM_INF			||990			info->lft.hard_byte_limit != XFRM_INF		||991			info->lft.soft_packet_limit != XFRM_INF		||992			info->lft.hard_packet_limit != XFRM_INF)993		return false;994 995	if (info->family != AF_INET || info->mode != XFRM_MODE_TUNNEL)996		return false;997 998	/* XXX: check xfrm algo, see xfrm_state_pack_algo(). */999 1000	return true;1001}1002 1003static int xfrm_state_check(int xfrm_sock, uint32_t seq, uint32_t spi,1004		struct in_addr src, struct in_addr dst,1005		struct xfrm_desc *desc)1006{1007	struct {1008		struct nlmsghdr		nh;1009		char			attrbuf[MAX_PAYLOAD];1010	} req;1011	struct {1012		struct nlmsghdr		nh;1013		union {1014			struct xfrm_usersa_info	info;1015			int error;1016		};1017		char			attrbuf[MAX_PAYLOAD];1018	} answer;1019	struct xfrm_address_filter filter = {};1020	bool found = false;1021 1022 1023	memset(&req, 0, sizeof(req));1024	req.nh.nlmsg_len	= NLMSG_LENGTH(0);1025	req.nh.nlmsg_type	= XFRM_MSG_GETSA;1026	req.nh.nlmsg_flags	= NLM_F_REQUEST | NLM_F_DUMP;1027	req.nh.nlmsg_seq	= seq;1028 1029	/*1030	 * Add dump filter by source address as there may be other tunnels1031	 * in this netns (if tests run in parallel).1032	 */1033	filter.family = AF_INET;1034	filter.splen = 0x1f;	/* 0xffffffff mask see addr_match() */1035	memcpy(&filter.saddr, &src, sizeof(src));1036	if (rtattr_pack(&req.nh, sizeof(req), XFRMA_ADDRESS_FILTER,1037				&filter, sizeof(filter)))1038		return -1;1039 1040	if (send(xfrm_sock, &req, req.nh.nlmsg_len, 0) < 0) {1041		pr_err("send()");1042		return -1;1043	}1044 1045	while (1) {1046		if (recv(xfrm_sock, &answer, sizeof(answer), 0) < 0) {1047			pr_err("recv()");1048			return -1;1049		}1050		if (answer.nh.nlmsg_type == NLMSG_ERROR) {1051			printk("NLMSG_ERROR: %d: %s",1052				answer.error, strerror(-answer.error));1053			return -1;1054		} else if (answer.nh.nlmsg_type == NLMSG_DONE) {1055			if (found)1056				return 0;1057			printk("didn't find allocated xfrm state in dump");1058			return -1;1059		} else if (answer.nh.nlmsg_type == XFRM_MSG_NEWSA) {1060			if (xfrm_usersa_found(&answer.info, spi, src, dst, desc))1061				found = true;1062		}1063	}1064}1065 1066static int xfrm_set(int xfrm_sock, uint32_t *seq,1067		struct in_addr src, struct in_addr dst,1068		struct in_addr tunsrc, struct in_addr tundst,1069		struct xfrm_desc *desc)1070{1071	int err;1072 1073	err = xfrm_state_add(xfrm_sock, (*seq)++, gen_spi(src), src, dst, desc);1074	if (err) {1075		printk("Failed to add xfrm state");1076		return -1;1077	}1078 1079	err = xfrm_state_add(xfrm_sock, (*seq)++, gen_spi(src), dst, src, desc);1080	if (err) {1081		printk("Failed to add xfrm state");1082		return -1;1083	}1084 1085	/* Check dumps for XFRM_MSG_GETSA */1086	err = xfrm_state_check(xfrm_sock, (*seq)++, gen_spi(src), src, dst, desc);1087	err |= xfrm_state_check(xfrm_sock, (*seq)++, gen_spi(src), dst, src, desc);1088	if (err) {1089		printk("Failed to check xfrm state");1090		return -1;1091	}1092 1093	return 0;1094}1095 1096static int xfrm_policy_add(int xfrm_sock, uint32_t seq, uint32_t spi,1097		struct in_addr src, struct in_addr dst, uint8_t dir,1098		struct in_addr tunsrc, struct in_addr tundst, uint8_t proto)1099{1100	struct {1101		struct nlmsghdr			nh;1102		struct xfrm_userpolicy_info	info;1103		char				attrbuf[MAX_PAYLOAD];1104	} req;1105	struct xfrm_user_tmpl tmpl;1106 1107	memset(&req, 0, sizeof(req));1108	memset(&tmpl, 0, sizeof(tmpl));1109	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.info));1110	req.nh.nlmsg_type	= XFRM_MSG_NEWPOLICY;1111	req.nh.nlmsg_flags	= NLM_F_REQUEST | NLM_F_ACK;1112	req.nh.nlmsg_seq	= seq;1113 1114	/* Fill selector. */1115	memcpy(&req.info.sel.daddr, &dst, sizeof(tundst));1116	memcpy(&req.info.sel.saddr, &src, sizeof(tunsrc));1117	req.info.sel.family		= AF_INET;1118	req.info.sel.prefixlen_d	= PREFIX_LEN;1119	req.info.sel.prefixlen_s	= PREFIX_LEN;1120 1121	/* Fill lifteme_cfg */1122	req.info.lft.soft_byte_limit	= XFRM_INF;1123	req.info.lft.hard_byte_limit	= XFRM_INF;1124	req.info.lft.soft_packet_limit	= XFRM_INF;1125	req.info.lft.hard_packet_limit	= XFRM_INF;1126 1127	req.info.dir = dir;1128 1129	/* Fill tmpl */1130	memcpy(&tmpl.id.daddr, &dst, sizeof(dst));1131	/* Note: zero-spi cannot be deleted */1132	tmpl.id.spi = spi;1133	tmpl.id.proto	= proto;1134	tmpl.family	= AF_INET;1135	memcpy(&tmpl.saddr, &src, sizeof(src));1136	tmpl.mode	= XFRM_MODE_TUNNEL;1137	tmpl.aalgos = (~(uint32_t)0);1138	tmpl.ealgos = (~(uint32_t)0);1139	tmpl.calgos = (~(uint32_t)0);1140 1141	if (rtattr_pack(&req.nh, sizeof(req), XFRMA_TMPL, &tmpl, sizeof(tmpl)))1142		return -1;1143 1144	if (send(xfrm_sock, &req, req.nh.nlmsg_len, 0) < 0) {1145		pr_err("send()");1146		return -1;1147	}1148 1149	return netlink_check_answer(xfrm_sock);1150}1151 1152static int xfrm_prepare(int xfrm_sock, uint32_t *seq,1153		struct in_addr src, struct in_addr dst,1154		struct in_addr tunsrc, struct in_addr tundst, uint8_t proto)1155{1156	if (xfrm_policy_add(xfrm_sock, (*seq)++, gen_spi(src), src, dst,1157				XFRM_POLICY_OUT, tunsrc, tundst, proto)) {1158		printk("Failed to add xfrm policy");1159		return -1;1160	}1161 1162	if (xfrm_policy_add(xfrm_sock, (*seq)++, gen_spi(src), dst, src,1163				XFRM_POLICY_IN, tunsrc, tundst, proto)) {1164		printk("Failed to add xfrm policy");1165		return -1;1166	}1167 1168	return 0;1169}1170 1171static int xfrm_policy_del(int xfrm_sock, uint32_t seq,1172		struct in_addr src, struct in_addr dst, uint8_t dir,1173		struct in_addr tunsrc, struct in_addr tundst)1174{1175	struct {1176		struct nlmsghdr			nh;1177		struct xfrm_userpolicy_id	id;1178		char				attrbuf[MAX_PAYLOAD];1179	} req;1180 1181	memset(&req, 0, sizeof(req));1182	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.id));1183	req.nh.nlmsg_type	= XFRM_MSG_DELPOLICY;1184	req.nh.nlmsg_flags	= NLM_F_REQUEST | NLM_F_ACK;1185	req.nh.nlmsg_seq	= seq;1186 1187	/* Fill id */1188	memcpy(&req.id.sel.daddr, &dst, sizeof(tundst));1189	memcpy(&req.id.sel.saddr, &src, sizeof(tunsrc));1190	req.id.sel.family		= AF_INET;1191	req.id.sel.prefixlen_d		= PREFIX_LEN;1192	req.id.sel.prefixlen_s		= PREFIX_LEN;1193	req.id.dir = dir;1194 1195	if (send(xfrm_sock, &req, req.nh.nlmsg_len, 0) < 0) {1196		pr_err("send()");1197		return -1;1198	}1199 1200	return netlink_check_answer(xfrm_sock);1201}1202 1203static int xfrm_cleanup(int xfrm_sock, uint32_t *seq,1204		struct in_addr src, struct in_addr dst,1205		struct in_addr tunsrc, struct in_addr tundst)1206{1207	if (xfrm_policy_del(xfrm_sock, (*seq)++, src, dst,1208				XFRM_POLICY_OUT, tunsrc, tundst)) {1209		printk("Failed to add xfrm policy");1210		return -1;1211	}1212 1213	if (xfrm_policy_del(xfrm_sock, (*seq)++, dst, src,1214				XFRM_POLICY_IN, tunsrc, tundst)) {1215		printk("Failed to add xfrm policy");1216		return -1;1217	}1218 1219	return 0;1220}1221 1222static int xfrm_state_del(int xfrm_sock, uint32_t seq, uint32_t spi,1223		struct in_addr src, struct in_addr dst, uint8_t proto)1224{1225	struct {1226		struct nlmsghdr		nh;1227		struct xfrm_usersa_id	id;1228		char			attrbuf[MAX_PAYLOAD];1229	} req;1230	xfrm_address_t saddr = {};1231 1232	memset(&req, 0, sizeof(req));1233	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.id));1234	req.nh.nlmsg_type	= XFRM_MSG_DELSA;1235	req.nh.nlmsg_flags	= NLM_F_REQUEST | NLM_F_ACK;1236	req.nh.nlmsg_seq	= seq;1237 1238	memcpy(&req.id.daddr, &dst, sizeof(dst));1239	req.id.family		= AF_INET;1240	req.id.proto		= proto;1241	/* Note: zero-spi cannot be deleted */1242	req.id.spi = spi;1243 1244	memcpy(&saddr, &src, sizeof(src));1245	if (rtattr_pack(&req.nh, sizeof(req), XFRMA_SRCADDR, &saddr, sizeof(saddr)))1246		return -1;1247 1248	if (send(xfrm_sock, &req, req.nh.nlmsg_len, 0) < 0) {1249		pr_err("send()");1250		return -1;1251	}1252 1253	return netlink_check_answer(xfrm_sock);1254}1255 1256static int xfrm_delete(int xfrm_sock, uint32_t *seq,1257		struct in_addr src, struct in_addr dst,1258		struct in_addr tunsrc, struct in_addr tundst, uint8_t proto)1259{1260	if (xfrm_state_del(xfrm_sock, (*seq)++, gen_spi(src), src, dst, proto)) {1261		printk("Failed to remove xfrm state");1262		return -1;1263	}1264 1265	if (xfrm_state_del(xfrm_sock, (*seq)++, gen_spi(src), dst, src, proto)) {1266		printk("Failed to remove xfrm state");1267		return -1;1268	}1269 1270	return 0;1271}1272 1273static int xfrm_state_allocspi(int xfrm_sock, uint32_t *seq,1274		uint32_t spi, uint8_t proto)1275{1276	struct {1277		struct nlmsghdr			nh;1278		struct xfrm_userspi_info	spi;1279	} req;1280	struct {1281		struct nlmsghdr			nh;1282		union {1283			struct xfrm_usersa_info	info;1284			int error;1285		};1286	} answer;1287 1288	memset(&req, 0, sizeof(req));1289	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.spi));1290	req.nh.nlmsg_type	= XFRM_MSG_ALLOCSPI;1291	req.nh.nlmsg_flags	= NLM_F_REQUEST;1292	req.nh.nlmsg_seq	= (*seq)++;1293 1294	req.spi.info.family	= AF_INET;1295	req.spi.min		= spi;1296	req.spi.max		= spi;1297	req.spi.info.id.proto	= proto;1298 1299	if (send(xfrm_sock, &req, req.nh.nlmsg_len, 0) < 0) {1300		pr_err("send()");1301		return KSFT_FAIL;1302	}1303 1304	if (recv(xfrm_sock, &answer, sizeof(answer), 0) < 0) {1305		pr_err("recv()");1306		return KSFT_FAIL;1307	} else if (answer.nh.nlmsg_type == XFRM_MSG_NEWSA) {1308		uint32_t new_spi = htonl(answer.info.id.spi);1309 1310		if (new_spi != spi) {1311			printk("allocated spi is different from requested: %#x != %#x",1312					new_spi, spi);1313			return KSFT_FAIL;1314		}1315		return KSFT_PASS;1316	} else if (answer.nh.nlmsg_type != NLMSG_ERROR) {1317		printk("expected NLMSG_ERROR, got %d", (int)answer.nh.nlmsg_type);1318		return KSFT_FAIL;1319	}1320 1321	printk("NLMSG_ERROR: %d: %s", answer.error, strerror(-answer.error));1322	return (answer.error) ? KSFT_FAIL : KSFT_PASS;1323}1324 1325static int netlink_sock_bind(int *sock, uint32_t *seq, int proto, uint32_t groups)1326{1327	struct sockaddr_nl snl = {};1328	socklen_t addr_len;1329	int ret = -1;1330 1331	snl.nl_family = AF_NETLINK;1332	snl.nl_groups = groups;1333 1334	if (netlink_sock(sock, seq, proto)) {1335		printk("Failed to open xfrm netlink socket");1336		return -1;1337	}1338 1339	if (bind(*sock, (struct sockaddr *)&snl, sizeof(snl)) < 0) {1340		pr_err("bind()");1341		goto out_close;1342	}1343 1344	addr_len = sizeof(snl);1345	if (getsockname(*sock, (struct sockaddr *)&snl, &addr_len) < 0) {1346		pr_err("getsockname()");1347		goto out_close;1348	}1349	if (addr_len != sizeof(snl)) {1350		printk("Wrong address length %d", addr_len);1351		goto out_close;1352	}1353	if (snl.nl_family != AF_NETLINK) {1354		printk("Wrong address family %d", snl.nl_family);1355		goto out_close;1356	}1357	return 0;1358 1359out_close:1360	close(*sock);1361	return ret;1362}1363 1364static int xfrm_monitor_acquire(int xfrm_sock, uint32_t *seq, unsigned int nr)1365{1366	struct {1367		struct nlmsghdr nh;1368		union {1369			struct xfrm_user_acquire acq;1370			int error;1371		};1372		char attrbuf[MAX_PAYLOAD];1373	} req;1374	struct xfrm_user_tmpl xfrm_tmpl = {};1375	int xfrm_listen = -1, ret = KSFT_FAIL;1376	uint32_t seq_listen;1377 1378	if (netlink_sock_bind(&xfrm_listen, &seq_listen, NETLINK_XFRM, XFRMNLGRP_ACQUIRE))1379		return KSFT_FAIL;1380 1381	memset(&req, 0, sizeof(req));1382	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.acq));1383	req.nh.nlmsg_type	= XFRM_MSG_ACQUIRE;1384	req.nh.nlmsg_flags	= NLM_F_REQUEST | NLM_F_ACK;1385	req.nh.nlmsg_seq	= (*seq)++;1386 1387	req.acq.policy.sel.family	= AF_INET;1388	req.acq.aalgos	= 0xfeed;1389	req.acq.ealgos	= 0xbaad;1390	req.acq.calgos	= 0xbabe;1391 1392	xfrm_tmpl.family = AF_INET;1393	xfrm_tmpl.id.proto = IPPROTO_ESP;1394	if (rtattr_pack(&req.nh, sizeof(req), XFRMA_TMPL, &xfrm_tmpl, sizeof(xfrm_tmpl)))1395		goto out_close;1396 1397	if (send(xfrm_sock, &req, req.nh.nlmsg_len, 0) < 0) {1398		pr_err("send()");1399		goto out_close;1400	}1401 1402	if (recv(xfrm_sock, &req, sizeof(req), 0) < 0) {1403		pr_err("recv()");1404		goto out_close;1405	} else if (req.nh.nlmsg_type != NLMSG_ERROR) {1406		printk("expected NLMSG_ERROR, got %d", (int)req.nh.nlmsg_type);1407		goto out_close;1408	}1409 1410	if (req.error) {1411		printk("NLMSG_ERROR: %d: %s", req.error, strerror(-req.error));1412		ret = req.error;1413		goto out_close;1414	}1415 1416	if (recv(xfrm_listen, &req, sizeof(req), 0) < 0) {1417		pr_err("recv()");1418		goto out_close;1419	}1420 1421	if (req.acq.aalgos != 0xfeed || req.acq.ealgos != 0xbaad1422			|| req.acq.calgos != 0xbabe) {1423		printk("xfrm_user_acquire has changed  %x %x %x",1424				req.acq.aalgos, req.acq.ealgos, req.acq.calgos);1425		goto out_close;1426	}1427 1428	ret = KSFT_PASS;1429out_close:1430	close(xfrm_listen);1431	return ret;1432}1433 1434static int xfrm_expire_state(int xfrm_sock, uint32_t *seq,1435		unsigned int nr, struct xfrm_desc *desc)1436{1437	struct {1438		struct nlmsghdr nh;1439		union {1440			struct xfrm_user_expire expire;1441			int error;1442		};1443	} req;1444	struct in_addr src, dst;1445	int xfrm_listen = -1, ret = KSFT_FAIL;1446	uint32_t seq_listen;1447 1448	src = inet_makeaddr(INADDR_B, child_ip(nr));1449	dst = inet_makeaddr(INADDR_B, grchild_ip(nr));1450 1451	if (xfrm_state_add(xfrm_sock, (*seq)++, gen_spi(src), src, dst, desc)) {1452		printk("Failed to add xfrm state");1453		return KSFT_FAIL;1454	}1455 1456	if (netlink_sock_bind(&xfrm_listen, &seq_listen, NETLINK_XFRM, XFRMNLGRP_EXPIRE))1457		return KSFT_FAIL;1458 1459	memset(&req, 0, sizeof(req));1460	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.expire));1461	req.nh.nlmsg_type	= XFRM_MSG_EXPIRE;1462	req.nh.nlmsg_flags	= NLM_F_REQUEST | NLM_F_ACK;1463	req.nh.nlmsg_seq	= (*seq)++;1464 1465	memcpy(&req.expire.state.id.daddr, &dst, sizeof(dst));1466	req.expire.state.id.spi		= gen_spi(src);1467	req.expire.state.id.proto	= desc->proto;1468	req.expire.state.family		= AF_INET;1469	req.expire.hard			= 0xff;1470 1471	if (send(xfrm_sock, &req, req.nh.nlmsg_len, 0) < 0) {1472		pr_err("send()");1473		goto out_close;1474	}1475 1476	if (recv(xfrm_sock, &req, sizeof(req), 0) < 0) {1477		pr_err("recv()");1478		goto out_close;1479	} else if (req.nh.nlmsg_type != NLMSG_ERROR) {1480		printk("expected NLMSG_ERROR, got %d", (int)req.nh.nlmsg_type);1481		goto out_close;1482	}1483 1484	if (req.error) {1485		printk("NLMSG_ERROR: %d: %s", req.error, strerror(-req.error));1486		ret = req.error;1487		goto out_close;1488	}1489 1490	if (recv(xfrm_listen, &req, sizeof(req), 0) < 0) {1491		pr_err("recv()");1492		goto out_close;1493	}1494 1495	if (req.expire.hard != 0x1) {1496		printk("expire.hard is not set: %x", req.expire.hard);1497		goto out_close;1498	}1499 1500	ret = KSFT_PASS;1501out_close:1502	close(xfrm_listen);1503	return ret;1504}1505 1506static int xfrm_expire_policy(int xfrm_sock, uint32_t *seq,1507		unsigned int nr, struct xfrm_desc *desc)1508{1509	struct {1510		struct nlmsghdr nh;1511		union {1512			struct xfrm_user_polexpire expire;1513			int error;1514		};1515	} req;1516	struct in_addr src, dst, tunsrc, tundst;1517	int xfrm_listen = -1, ret = KSFT_FAIL;1518	uint32_t seq_listen;1519 1520	src = inet_makeaddr(INADDR_B, child_ip(nr));1521	dst = inet_makeaddr(INADDR_B, grchild_ip(nr));1522	tunsrc = inet_makeaddr(INADDR_A, child_ip(nr));1523	tundst = inet_makeaddr(INADDR_A, grchild_ip(nr));1524 1525	if (xfrm_policy_add(xfrm_sock, (*seq)++, gen_spi(src), src, dst,1526				XFRM_POLICY_OUT, tunsrc, tundst, desc->proto)) {1527		printk("Failed to add xfrm policy");1528		return KSFT_FAIL;1529	}1530 1531	if (netlink_sock_bind(&xfrm_listen, &seq_listen, NETLINK_XFRM, XFRMNLGRP_EXPIRE))1532		return KSFT_FAIL;1533 1534	memset(&req, 0, sizeof(req));1535	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.expire));1536	req.nh.nlmsg_type	= XFRM_MSG_POLEXPIRE;1537	req.nh.nlmsg_flags	= NLM_F_REQUEST | NLM_F_ACK;1538	req.nh.nlmsg_seq	= (*seq)++;1539 1540	/* Fill selector. */1541	memcpy(&req.expire.pol.sel.daddr, &dst, sizeof(tundst));1542	memcpy(&req.expire.pol.sel.saddr, &src, sizeof(tunsrc));1543	req.expire.pol.sel.family	= AF_INET;1544	req.expire.pol.sel.prefixlen_d	= PREFIX_LEN;1545	req.expire.pol.sel.prefixlen_s	= PREFIX_LEN;1546	req.expire.pol.dir		= XFRM_POLICY_OUT;1547	req.expire.hard			= 0xff;1548 1549	if (send(xfrm_sock, &req, req.nh.nlmsg_len, 0) < 0) {1550		pr_err("send()");1551		goto out_close;1552	}1553 1554	if (recv(xfrm_sock, &req, sizeof(req), 0) < 0) {1555		pr_err("recv()");1556		goto out_close;1557	} else if (req.nh.nlmsg_type != NLMSG_ERROR) {1558		printk("expected NLMSG_ERROR, got %d", (int)req.nh.nlmsg_type);1559		goto out_close;1560	}1561 1562	if (req.error) {1563		printk("NLMSG_ERROR: %d: %s", req.error, strerror(-req.error));1564		ret = req.error;1565		goto out_close;1566	}1567 1568	if (recv(xfrm_listen, &req, sizeof(req), 0) < 0) {1569		pr_err("recv()");1570		goto out_close;1571	}1572 1573	if (req.expire.hard != 0x1) {1574		printk("expire.hard is not set: %x", req.expire.hard);1575		goto out_close;1576	}1577 1578	ret = KSFT_PASS;1579out_close:1580	close(xfrm_listen);1581	return ret;1582}1583 1584static int xfrm_spdinfo_set_thresh(int xfrm_sock, uint32_t *seq,1585		unsigned thresh4_l, unsigned thresh4_r,1586		unsigned thresh6_l, unsigned thresh6_r,1587		bool add_bad_attr)1588 1589{1590	struct {1591		struct nlmsghdr		nh;1592		union {1593			uint32_t	unused;1594			int		error;1595		};1596		char			attrbuf[MAX_PAYLOAD];1597	} req;1598	struct xfrmu_spdhthresh thresh;1599 1600	memset(&req, 0, sizeof(req));1601	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.unused));1602	req.nh.nlmsg_type	= XFRM_MSG_NEWSPDINFO;1603	req.nh.nlmsg_flags	= NLM_F_REQUEST | NLM_F_ACK;1604	req.nh.nlmsg_seq	= (*seq)++;1605 1606	thresh.lbits = thresh4_l;1607	thresh.rbits = thresh4_r;1608	if (rtattr_pack(&req.nh, sizeof(req), XFRMA_SPD_IPV4_HTHRESH, &thresh, sizeof(thresh)))1609		return -1;1610 1611	thresh.lbits = thresh6_l;1612	thresh.rbits = thresh6_r;1613	if (rtattr_pack(&req.nh, sizeof(req), XFRMA_SPD_IPV6_HTHRESH, &thresh, sizeof(thresh)))1614		return -1;1615 1616	if (add_bad_attr) {1617		BUILD_BUG_ON(XFRMA_IF_ID <= XFRMA_SPD_MAX + 1);1618		if (rtattr_pack(&req.nh, sizeof(req), XFRMA_IF_ID, NULL, 0)) {1619			pr_err("adding attribute failed: no space");1620			return -1;1621		}1622	}1623 1624	if (send(xfrm_sock, &req, req.nh.nlmsg_len, 0) < 0) {1625		pr_err("send()");1626		return -1;1627	}1628 1629	if (recv(xfrm_sock, &req, sizeof(req), 0) < 0) {1630		pr_err("recv()");1631		return -1;1632	} else if (req.nh.nlmsg_type != NLMSG_ERROR) {1633		printk("expected NLMSG_ERROR, got %d", (int)req.nh.nlmsg_type);1634		return -1;1635	}1636 1637	if (req.error) {1638		printk("NLMSG_ERROR: %d: %s", req.error, strerror(-req.error));1639		return -1;1640	}1641 1642	return 0;1643}1644 1645static int xfrm_spdinfo_attrs(int xfrm_sock, uint32_t *seq)1646{1647	struct {1648		struct nlmsghdr			nh;1649		union {1650			uint32_t	unused;1651			int		error;1652		};1653		char			attrbuf[MAX_PAYLOAD];1654	} req;1655 1656	if (xfrm_spdinfo_set_thresh(xfrm_sock, seq, 32, 31, 120, 16, false)) {1657		pr_err("Can't set SPD HTHRESH");1658		return KSFT_FAIL;1659	}1660 1661	memset(&req, 0, sizeof(req));1662 1663	req.nh.nlmsg_len	= NLMSG_LENGTH(sizeof(req.unused));1664	req.nh.nlmsg_type	= XFRM_MSG_GETSPDINFO;1665	req.nh.nlmsg_flags	= NLM_F_REQUEST;1666	req.nh.nlmsg_seq	= (*seq)++;1667	if (send(xfrm_sock, &req, req.nh.nlmsg_len, 0) < 0) {1668		pr_err("send()");1669		return KSFT_FAIL;1670	}1671 1672	if (recv(xfrm_sock, &req, sizeof(req), 0) < 0) {1673		pr_err("recv()");1674		return KSFT_FAIL;1675	} else if (req.nh.nlmsg_type == XFRM_MSG_NEWSPDINFO) {1676		size_t len = NLMSG_PAYLOAD(&req.nh, sizeof(req.unused));1677		struct rtattr *attr = (void *)req.attrbuf;1678		int got_thresh = 0;1679 1680		for (; RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) {1681			if (attr->rta_type == XFRMA_SPD_IPV4_HTHRESH) {1682				struct xfrmu_spdhthresh *t = RTA_DATA(attr);1683 1684				got_thresh++;1685				if (t->lbits != 32 || t->rbits != 31) {1686					pr_err("thresh differ: %u, %u",1687							t->lbits, t->rbits);1688					return KSFT_FAIL;1689				}1690			}1691			if (attr->rta_type == XFRMA_SPD_IPV6_HTHRESH) {1692				struct xfrmu_spdhthresh *t = RTA_DATA(attr);1693 1694				got_thresh++;1695				if (t->lbits != 120 || t->rbits != 16) {1696					pr_err("thresh differ: %u, %u",1697							t->lbits, t->rbits);1698					return KSFT_FAIL;1699				}1700			}1701		}1702		if (got_thresh != 2) {1703			pr_err("only %d thresh returned by XFRM_MSG_GETSPDINFO", got_thresh);1704			return KSFT_FAIL;1705		}1706	} else if (req.nh.nlmsg_type != NLMSG_ERROR) {1707		printk("expected NLMSG_ERROR, got %d", (int)req.nh.nlmsg_type);1708		return KSFT_FAIL;1709	} else {1710		printk("NLMSG_ERROR: %d: %s", req.error, strerror(-req.error));1711		return -1;1712	}1713 1714	/* Restore the default */1715	if (xfrm_spdinfo_set_thresh(xfrm_sock, seq, 32, 32, 128, 128, false)) {1716		pr_err("Can't restore SPD HTHRESH");1717		return KSFT_FAIL;1718	}1719 1720	/*1721	 * At this moment xfrm uses nlmsg_parse_deprecated(), which1722	 * implies NL_VALIDATE_LIBERAL - ignoring attributes with1723	 * (type > maxtype). nla_parse_depricated_strict() would enforce1724	 * it. Or even stricter nla_parse().1725	 * Right now it's not expected to fail, but to be ignored.1726	 */1727	if (xfrm_spdinfo_set_thresh(xfrm_sock, seq, 32, 32, 128, 128, true))1728		return KSFT_PASS;1729 1730	return KSFT_PASS;1731}1732 1733static int child_serv(int xfrm_sock, uint32_t *seq,1734		unsigned int nr, int cmd_fd, void *buf, struct xfrm_desc *desc)1735{1736	struct in_addr src, dst, tunsrc, tundst;1737	struct test_desc msg;1738	int ret = KSFT_FAIL;1739 1740	src = inet_makeaddr(INADDR_B, child_ip(nr));1741	dst = inet_makeaddr(INADDR_B, grchild_ip(nr));1742	tunsrc = inet_makeaddr(INADDR_A, child_ip(nr));1743	tundst = inet_makeaddr(INADDR_A, grchild_ip(nr));1744 1745	/* UDP pinging without xfrm */1746	if (do_ping(cmd_fd, buf, page_size, src, true, 0, 0, udp_ping_send)) {1747		printk("ping failed before setting xfrm");1748		return KSFT_FAIL;1749	}1750 1751	memset(&msg, 0, sizeof(msg));1752	msg.type = MSG_XFRM_PREPARE;1753	memcpy(&msg.body.xfrm_desc, desc, sizeof(*desc));1754	write_msg(cmd_fd, &msg, 1);1755 1756	if (xfrm_prepare(xfrm_sock, seq, src, dst, tunsrc, tundst, desc->proto)) {1757		printk("failed to prepare xfrm");1758		goto cleanup;1759	}1760 1761	memset(&msg, 0, sizeof(msg));1762	msg.type = MSG_XFRM_ADD;1763	memcpy(&msg.body.xfrm_desc, desc, sizeof(*desc));1764	write_msg(cmd_fd, &msg, 1);1765	if (xfrm_set(xfrm_sock, seq, src, dst, tunsrc, tundst, desc)) {1766		printk("failed to set xfrm");1767		goto delete;1768	}1769 1770	/* UDP pinging with xfrm tunnel */1771	if (do_ping(cmd_fd, buf, page_size, tunsrc,1772				true, 0, 0, udp_ping_send)) {1773		printk("ping failed for xfrm");1774		goto delete;1775	}1776 1777	ret = KSFT_PASS;1778delete:1779	/* xfrm delete */1780	memset(&msg, 0, sizeof(msg));1781	msg.type = MSG_XFRM_DEL;1782	memcpy(&msg.body.xfrm_desc, desc, sizeof(*desc));1783	write_msg(cmd_fd, &msg, 1);1784 1785	if (xfrm_delete(xfrm_sock, seq, src, dst, tunsrc, tundst, desc->proto)) {1786		printk("failed ping to remove xfrm");1787		ret = KSFT_FAIL;1788	}1789 1790cleanup:1791	memset(&msg, 0, sizeof(msg));1792	msg.type = MSG_XFRM_CLEANUP;1793	memcpy(&msg.body.xfrm_desc, desc, sizeof(*desc));1794	write_msg(cmd_fd, &msg, 1);1795	if (xfrm_cleanup(xfrm_sock, seq, src, dst, tunsrc, tundst)) {1796		printk("failed ping to cleanup xfrm");1797		ret = KSFT_FAIL;1798	}1799	return ret;1800}1801 1802static int child_f(unsigned int nr, int test_desc_fd, int cmd_fd, void *buf)1803{1804	struct xfrm_desc desc;1805	struct test_desc msg;1806	int xfrm_sock = -1;1807	uint32_t seq;1808 1809	if (switch_ns(nsfd_childa))1810		exit(KSFT_FAIL);1811 1812	if (netlink_sock(&xfrm_sock, &seq, NETLINK_XFRM)) {1813		printk("Failed to open xfrm netlink socket");1814		exit(KSFT_FAIL);1815	}1816 1817	/* Check that seq sock is ready, just for sure. */1818	memset(&msg, 0, sizeof(msg));1819	msg.type = MSG_ACK;1820	write_msg(cmd_fd, &msg, 1);1821	read_msg(cmd_fd, &msg, 1);1822	if (msg.type != MSG_ACK) {1823		printk("Ack failed");1824		exit(KSFT_FAIL);1825	}1826 1827	for (;;) {1828		ssize_t received = read(test_desc_fd, &desc, sizeof(desc));1829		int ret;1830 1831		if (received == 0) /* EOF */1832			break;1833 1834		if (received != sizeof(desc)) {1835			pr_err("read() returned %zd", received);1836			exit(KSFT_FAIL);1837		}1838 1839		switch (desc.type) {1840		case CREATE_TUNNEL:1841			ret = child_serv(xfrm_sock, &seq, nr,1842					 cmd_fd, buf, &desc);1843			break;1844		case ALLOCATE_SPI:1845			ret = xfrm_state_allocspi(xfrm_sock, &seq,1846						  -1, desc.proto);1847			break;1848		case MONITOR_ACQUIRE:1849			ret = xfrm_monitor_acquire(xfrm_sock, &seq, nr);1850			break;1851		case EXPIRE_STATE:1852			ret = xfrm_expire_state(xfrm_sock, &seq, nr, &desc);1853			break;1854		case EXPIRE_POLICY:1855			ret = xfrm_expire_policy(xfrm_sock, &seq, nr, &desc);1856			break;1857		case SPDINFO_ATTRS:1858			ret = xfrm_spdinfo_attrs(xfrm_sock, &seq);1859			break;1860		default:1861			printk("Unknown desc type %d", desc.type);1862			exit(KSFT_FAIL);1863		}1864		write_test_result(ret, &desc);1865	}1866 1867	close(xfrm_sock);1868 1869	msg.type = MSG_EXIT;1870	write_msg(cmd_fd, &msg, 1);1871	exit(KSFT_PASS);1872}1873 1874static void grand_child_serv(unsigned int nr, int cmd_fd, void *buf,1875		struct test_desc *msg, int xfrm_sock, uint32_t *seq)1876{1877	struct in_addr src, dst, tunsrc, tundst;1878	bool tun_reply;1879	struct xfrm_desc *desc = &msg->body.xfrm_desc;1880 1881	src = inet_makeaddr(INADDR_B, grchild_ip(nr));1882	dst = inet_makeaddr(INADDR_B, child_ip(nr));1883	tunsrc = inet_makeaddr(INADDR_A, grchild_ip(nr));1884	tundst = inet_makeaddr(INADDR_A, child_ip(nr));1885 1886	switch (msg->type) {1887	case MSG_EXIT:1888		exit(KSFT_PASS);1889	case MSG_ACK:1890		write_msg(cmd_fd, msg, 1);1891		break;1892	case MSG_PING:1893		tun_reply = memcmp(&dst, &msg->body.ping.reply_ip, sizeof(in_addr_t));1894		/* UDP pinging without xfrm */1895		if (do_ping(cmd_fd, buf, page_size, tun_reply ? tunsrc : src,1896				false, msg->body.ping.port,1897				msg->body.ping.reply_ip, udp_ping_reply)) {1898			printk("ping failed before setting xfrm");1899		}1900		break;1901	case MSG_XFRM_PREPARE:1902		if (xfrm_prepare(xfrm_sock, seq, src, dst, tunsrc, tundst,1903					desc->proto)) {1904			xfrm_cleanup(xfrm_sock, seq, src, dst, tunsrc, tundst);1905			printk("failed to prepare xfrm");1906		}1907		break;1908	case MSG_XFRM_ADD:1909		if (xfrm_set(xfrm_sock, seq, src, dst, tunsrc, tundst, desc)) {1910			xfrm_cleanup(xfrm_sock, seq, src, dst, tunsrc, tundst);1911			printk("failed to set xfrm");1912		}1913		break;1914	case MSG_XFRM_DEL:1915		if (xfrm_delete(xfrm_sock, seq, src, dst, tunsrc, tundst,1916					desc->proto)) {1917			xfrm_cleanup(xfrm_sock, seq, src, dst, tunsrc, tundst);1918			printk("failed to remove xfrm");1919		}1920		break;1921	case MSG_XFRM_CLEANUP:1922		if (xfrm_cleanup(xfrm_sock, seq, src, dst, tunsrc, tundst)) {1923			printk("failed to cleanup xfrm");1924		}1925		break;1926	default:1927		printk("got unknown msg type %d", msg->type);1928	}1929}1930 1931static int grand_child_f(unsigned int nr, int cmd_fd, void *buf)1932{1933	struct test_desc msg;1934	int xfrm_sock = -1;1935	uint32_t seq;1936 1937	if (switch_ns(nsfd_childb))1938		exit(KSFT_FAIL);1939 1940	if (netlink_sock(&xfrm_sock, &seq, NETLINK_XFRM)) {1941		printk("Failed to open xfrm netlink socket");1942		exit(KSFT_FAIL);1943	}1944 1945	do {1946		read_msg(cmd_fd, &msg, 1);1947		grand_child_serv(nr, cmd_fd, buf, &msg, xfrm_sock, &seq);1948	} while (1);1949 1950	close(xfrm_sock);1951	exit(KSFT_FAIL);1952}1953 1954static int start_child(unsigned int nr, char *veth, int test_desc_fd[2])1955{1956	int cmd_sock[2];1957	void *data_map;1958	pid_t child;1959 1960	if (init_child(nsfd_childa, veth, child_ip(nr), grchild_ip(nr)))1961		return -1;1962 1963	if (init_child(nsfd_childb, veth, grchild_ip(nr), child_ip(nr)))1964		return -1;1965 1966	child = fork();1967	if (child < 0) {1968		pr_err("fork()");1969		return -1;1970	} else if (child) {1971		/* in parent - selftest */1972		return switch_ns(nsfd_parent);1973	}1974 1975	if (close(test_desc_fd[1])) {1976		pr_err("close()");1977		return -1;1978	}1979 1980	/* child */1981	data_map = mmap(0, page_size, PROT_READ | PROT_WRITE,1982			MAP_SHARED | MAP_ANONYMOUS, -1, 0);1983	if (data_map == MAP_FAILED) {1984		pr_err("mmap()");1985		return -1;1986	}1987 1988	randomize_buffer(data_map, page_size);1989 1990	if (socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, cmd_sock)) {1991		pr_err("socketpair()");1992		return -1;1993	}1994 1995	child = fork();1996	if (child < 0) {1997		pr_err("fork()");1998		return -1;1999	} else if (child) {2000		if (close(cmd_sock[0])) {2001			pr_err("close()");2002			return -1;2003		}2004		return child_f(nr, test_desc_fd[0], cmd_sock[1], data_map);2005	}2006	if (close(cmd_sock[1])) {2007		pr_err("close()");2008		return -1;2009	}2010	return grand_child_f(nr, cmd_sock[0], data_map);2011}2012 2013static void exit_usage(char **argv)2014{2015	printk("Usage: %s [nr_process]", argv[0]);2016	exit(KSFT_FAIL);2017}2018 2019static int __write_desc(int test_desc_fd, struct xfrm_desc *desc)2020{2021	ssize_t ret;2022 2023	ret = write(test_desc_fd, desc, sizeof(*desc));2024 2025	if (ret == sizeof(*desc))2026		return 0;2027 2028	pr_err("Writing test's desc failed %ld", ret);2029 2030	return -1;2031}2032 2033static int write_desc(int proto, int test_desc_fd,2034		char *a, char *e, char *c, char *ae)2035{2036	struct xfrm_desc desc = {};2037 2038	desc.type = CREATE_TUNNEL;2039	desc.proto = proto;2040 2041	if (a)2042		strncpy(desc.a_algo, a, ALGO_LEN - 1);2043	if (e)2044		strncpy(desc.e_algo, e, ALGO_LEN - 1);2045	if (c)2046		strncpy(desc.c_algo, c, ALGO_LEN - 1);2047	if (ae)2048		strncpy(desc.ae_algo, ae, ALGO_LEN - 1);2049 2050	return __write_desc(test_desc_fd, &desc);2051}2052 2053int proto_list[] = { IPPROTO_AH, IPPROTO_COMP, IPPROTO_ESP };2054char *ah_list[] = {2055	"digest_null", "hmac(md5)", "hmac(sha1)", "hmac(sha256)",2056	"hmac(sha384)", "hmac(sha512)", "hmac(rmd160)",2057	"xcbc(aes)", "cmac(aes)"2058};2059char *comp_list[] = {2060	"deflate",2061#if 02062	/* No compression backend realization */2063	"lzs", "lzjh"2064#endif2065};2066char *e_list[] = {2067	"ecb(cipher_null)", "cbc(des)", "cbc(des3_ede)", "cbc(cast5)",2068	"cbc(blowfish)", "cbc(aes)", "cbc(serpent)", "cbc(camellia)",2069	"cbc(twofish)", "rfc3686(ctr(aes))"2070};2071char *ae_list[] = {2072#if 02073	/* not implemented */2074	"rfc4106(gcm(aes))", "rfc4309(ccm(aes))", "rfc4543(gcm(aes))",2075	"rfc7539esp(chacha20,poly1305)"2076#endif2077};2078 2079const unsigned int proto_plan = ARRAY_SIZE(ah_list) + ARRAY_SIZE(comp_list) \2080				+ (ARRAY_SIZE(ah_list) * ARRAY_SIZE(e_list)) \2081				+ ARRAY_SIZE(ae_list);2082 2083static int write_proto_plan(int fd, int proto)2084{2085	unsigned int i;2086 2087	switch (proto) {2088	case IPPROTO_AH:2089		for (i = 0; i < ARRAY_SIZE(ah_list); i++) {2090			if (write_desc(proto, fd, ah_list[i], 0, 0, 0))2091				return -1;2092		}2093		break;2094	case IPPROTO_COMP:2095		for (i = 0; i < ARRAY_SIZE(comp_list); i++) {2096			if (write_desc(proto, fd, 0, 0, comp_list[i], 0))2097				return -1;2098		}2099		break;2100	case IPPROTO_ESP:2101		for (i = 0; i < ARRAY_SIZE(ah_list); i++) {2102			int j;2103 2104			for (j = 0; j < ARRAY_SIZE(e_list); j++) {2105				if (write_desc(proto, fd, ah_list[i],2106							e_list[j], 0, 0))2107					return -1;2108			}2109		}2110		for (i = 0; i < ARRAY_SIZE(ae_list); i++) {2111			if (write_desc(proto, fd, 0, 0, 0, ae_list[i]))2112				return -1;2113		}2114		break;2115	default:2116		printk("BUG: Specified unknown proto %d", proto);2117		return -1;2118	}2119 2120	return 0;2121}2122 2123/*2124 * Some structures in xfrm uapi header differ in size between2125 * 64-bit and 32-bit ABI:2126 *2127 *             32-bit UABI               |            64-bit UABI2128 *  -------------------------------------|-------------------------------------2129 *   sizeof(xfrm_usersa_info)     = 220  |  sizeof(xfrm_usersa_info)     = 2242130 *   sizeof(xfrm_userpolicy_info) = 164  |  sizeof(xfrm_userpolicy_info) = 1682131 *   sizeof(xfrm_userspi_info)    = 228  |  sizeof(xfrm_userspi_info)    = 2322132 *   sizeof(xfrm_user_acquire)    = 276  |  sizeof(xfrm_user_acquire)    = 2802133 *   sizeof(xfrm_user_expire)     = 224  |  sizeof(xfrm_user_expire)     = 2322134 *   sizeof(xfrm_user_polexpire)  = 168  |  sizeof(xfrm_user_polexpire)  = 1762135 *2136 * Check the affected by the UABI difference structures.2137 * Also, check translation for xfrm_set_spdinfo: it has it's own attributes2138 * which needs to be correctly copied, but not translated.2139 */2140const unsigned int compat_plan = 5;2141static int write_compat_struct_tests(int test_desc_fd)2142{2143	struct xfrm_desc desc = {};2144 2145	desc.type = ALLOCATE_SPI;2146	desc.proto = IPPROTO_AH;2147	strncpy(desc.a_algo, ah_list[0], ALGO_LEN - 1);2148 2149	if (__write_desc(test_desc_fd, &desc))2150		return -1;2151 2152	desc.type = MONITOR_ACQUIRE;2153	if (__write_desc(test_desc_fd, &desc))2154		return -1;2155 2156	desc.type = EXPIRE_STATE;2157	if (__write_desc(test_desc_fd, &desc))2158		return -1;2159 2160	desc.type = EXPIRE_POLICY;2161	if (__write_desc(test_desc_fd, &desc))2162		return -1;2163 2164	desc.type = SPDINFO_ATTRS;2165	if (__write_desc(test_desc_fd, &desc))2166		return -1;2167 2168	return 0;2169}2170 2171static int write_test_plan(int test_desc_fd)2172{2173	unsigned int i;2174	pid_t child;2175 2176	child = fork();2177	if (child < 0) {2178		pr_err("fork()");2179		return -1;2180	}2181	if (child) {2182		if (close(test_desc_fd))2183			printk("close(): %m");2184		return 0;2185	}2186 2187	if (write_compat_struct_tests(test_desc_fd))2188		exit(KSFT_FAIL);2189 2190	for (i = 0; i < ARRAY_SIZE(proto_list); i++) {2191		if (write_proto_plan(test_desc_fd, proto_list[i]))2192			exit(KSFT_FAIL);2193	}2194 2195	exit(KSFT_PASS);2196}2197 2198static int children_cleanup(void)2199{2200	unsigned ret = KSFT_PASS;2201 2202	while (1) {2203		int status;2204		pid_t p = wait(&status);2205 2206		if ((p < 0) && errno == ECHILD)2207			break;2208 2209		if (p < 0) {2210			pr_err("wait()");2211			return KSFT_FAIL;2212		}2213 2214		if (!WIFEXITED(status)) {2215			ret = KSFT_FAIL;2216			continue;2217		}2218 2219		if (WEXITSTATUS(status) == KSFT_FAIL)2220			ret = KSFT_FAIL;2221	}2222 2223	return ret;2224}2225 2226typedef void (*print_res)(const char *, ...);2227 2228static int check_results(void)2229{2230	struct test_result tr = {};2231	struct xfrm_desc *d = &tr.desc;2232	int ret = KSFT_PASS;2233 2234	while (1) {2235		ssize_t received = read(results_fd[0], &tr, sizeof(tr));2236		print_res result;2237 2238		if (received == 0) /* EOF */2239			break;2240 2241		if (received != sizeof(tr)) {2242			pr_err("read() returned %zd", received);2243			return KSFT_FAIL;2244		}2245 2246		switch (tr.res) {2247		case KSFT_PASS:2248			result = ksft_test_result_pass;2249			break;2250		case KSFT_FAIL:2251		default:2252			result = ksft_test_result_fail;2253			ret = KSFT_FAIL;2254		}2255 2256		result(" %s: [%u, '%s', '%s', '%s', '%s', %u]\n",2257		       desc_name[d->type], (unsigned int)d->proto, d->a_algo,2258		       d->e_algo, d->c_algo, d->ae_algo, d->icv_len);2259	}2260 2261	return ret;2262}2263 2264int main(int argc, char **argv)2265{2266	long nr_process = 1;2267	int route_sock = -1, ret = KSFT_SKIP;2268	int test_desc_fd[2];2269	uint32_t route_seq;2270	unsigned int i;2271 2272	if (argc > 2)2273		exit_usage(argv);2274 2275	if (argc > 1) {2276		char *endptr;2277 2278		errno = 0;2279		nr_process = strtol(argv[1], &endptr, 10);2280		if ((errno == ERANGE && (nr_process == LONG_MAX || nr_process == LONG_MIN))2281				|| (errno != 0 && nr_process == 0)2282				|| (endptr == argv[1]) || (*endptr != '\0')) {2283			printk("Failed to parse [nr_process]");2284			exit_usage(argv);2285		}2286 2287		if (nr_process > MAX_PROCESSES || nr_process < 1) {2288			printk("nr_process should be between [1; %u]",2289					MAX_PROCESSES);2290			exit_usage(argv);2291		}2292	}2293 2294	srand(time(NULL));2295	page_size = sysconf(_SC_PAGESIZE);2296	if (page_size < 1)2297		ksft_exit_skip("sysconf(): %m\n");2298 2299	if (pipe2(test_desc_fd, O_DIRECT) < 0)2300		ksft_exit_skip("pipe(): %m\n");2301 2302	if (pipe2(results_fd, O_DIRECT) < 0)2303		ksft_exit_skip("pipe(): %m\n");2304 2305	if (init_namespaces())2306		ksft_exit_skip("Failed to create namespaces\n");2307 2308	if (netlink_sock(&route_sock, &route_seq, NETLINK_ROUTE))2309		ksft_exit_skip("Failed to open netlink route socket\n");2310 2311	for (i = 0; i < nr_process; i++) {2312		char veth[VETH_LEN];2313 2314		snprintf(veth, VETH_LEN, VETH_FMT, i);2315 2316		if (veth_add(route_sock, route_seq++, veth, nsfd_childa, veth, nsfd_childb)) {2317			close(route_sock);2318			ksft_exit_fail_msg("Failed to create veth device");2319		}2320 2321		if (start_child(i, veth, test_desc_fd)) {2322			close(route_sock);2323			ksft_exit_fail_msg("Child %u failed to start", i);2324		}2325	}2326 2327	if (close(route_sock) || close(test_desc_fd[0]) || close(results_fd[1]))2328		ksft_exit_fail_msg("close(): %m");2329 2330	ksft_set_plan(proto_plan + compat_plan);2331 2332	if (write_test_plan(test_desc_fd[1]))2333		ksft_exit_fail_msg("Failed to write test plan to pipe");2334 2335	ret = check_results();2336 2337	if (children_cleanup() == KSFT_FAIL)2338		exit(KSFT_FAIL);2339 2340	exit(ret);2341}2342