Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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