^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) }