1 // SPDX-License-Identifier: GPL-2.0
3 * ipsec.c - Check xfrm on veth inside a net-ns.
4 * Copyright (c) 2018 Dmitry Safonov
10 #include <asm/types.h>
14 #include <linux/limits.h>
15 #include <linux/netlink.h>
16 #include <linux/random.h>
17 #include <linux/rtnetlink.h>
18 #include <linux/veth.h>
19 #include <linux/xfrm.h>
20 #include <netinet/in.h>
29 #include <sys/socket.h>
31 #include <sys/syscall.h>
32 #include <sys/types.h>
37 #include "../kselftest.h"
39 #define printk(fmt, ...) \
40 ksft_print_msg("%d[%u] " fmt "\n", getpid(), __LINE__, ##__VA_ARGS__)
42 #define pr_err(fmt, ...) printk(fmt ": %m", ##__VA_ARGS__)
44 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
46 #define IPV4_STR_SZ 16 /* xxx.xxx.xxx.xxx is longest + \0 */
47 #define MAX_PAYLOAD 2048
48 #define XFRM_ALGO_KEY_BUF_SIZE 512
49 #define MAX_PROCESSES (1 << 14) /* /16 mask divided by /30 subnets */
50 #define INADDR_A ((in_addr_t) 0x0a000000) /* 10.0.0.0 */
51 #define INADDR_B ((in_addr_t) 0xc0a80000) /* 192.168.0.0 */
53 /* /30 mask for one veth connection */
55 #define child_ip(nr) (4*nr + 1)
56 #define grchild_ip(nr) (4*nr + 2)
58 #define VETH_FMT "ktst-%d"
61 #define XFRM_ALGO_NR_KEYS 29
63 static int nsfd_parent
= -1;
64 static int nsfd_childa
= -1;
65 static int nsfd_childb
= -1;
66 static long page_size
;
69 * ksft_cnt is static in kselftest, so isn't shared with children.
70 * We have to send a test result back to parent and count there.
71 * results_fd is a pipe with test feedback from children.
73 static int results_fd
[2];
75 const unsigned int ping_delay_nsec
= 50 * 1000 * 1000;
76 const unsigned int ping_timeout
= 300;
77 const unsigned int ping_count
= 100;
78 const unsigned int ping_success
= 80;
80 struct xfrm_key_entry
{
85 struct xfrm_key_entry xfrm_key_entries
[] = {
87 {"ecb(cipher_null)", 0},
93 {"cbc(serpent)", 128},
95 {"hmac(rmd160)", 160},
96 {"cbc(des3_ede)", 192},
97 {"hmac(sha256)", 256},
99 {"cbc(camellia)", 256},
100 {"cbc(twofish)", 256},
101 {"rfc3686(ctr(aes))", 288},
102 {"hmac(sha384)", 384},
103 {"cbc(blowfish)", 448},
104 {"hmac(sha512)", 512},
105 {"rfc4106(gcm(aes))-128", 160},
106 {"rfc4543(gcm(aes))-128", 160},
107 {"rfc4309(ccm(aes))-128", 152},
108 {"rfc4106(gcm(aes))-192", 224},
109 {"rfc4543(gcm(aes))-192", 224},
110 {"rfc4309(ccm(aes))-192", 216},
111 {"rfc4106(gcm(aes))-256", 288},
112 {"rfc4543(gcm(aes))-256", 288},
113 {"rfc4309(ccm(aes))-256", 280},
114 {"rfc7539(chacha20,poly1305)-128", 0}
117 static void randomize_buffer(void *buf
, size_t buflen
)
120 size_t words
= buflen
/ sizeof(int);
121 size_t leftover
= buflen
% sizeof(int);
132 memcpy(buf
+ buflen
- leftover
, &tmp
, leftover
);
138 static int unshare_open(void)
140 const char *netns_path
= "/proc/self/ns/net";
143 if (unshare(CLONE_NEWNET
) != 0) {
148 fd
= open(netns_path
, O_RDONLY
);
150 pr_err("open(%s)", netns_path
);
157 static int switch_ns(int fd
)
159 if (setns(fd
, CLONE_NEWNET
)) {
167 * Running the test inside a new parent net namespace to bother less
168 * about cleanup on error-path.
170 static int init_namespaces(void)
172 nsfd_parent
= unshare_open();
173 if (nsfd_parent
<= 0)
176 nsfd_childa
= unshare_open();
177 if (nsfd_childa
<= 0)
180 if (switch_ns(nsfd_parent
))
183 nsfd_childb
= unshare_open();
184 if (nsfd_childb
<= 0)
187 if (switch_ns(nsfd_parent
))
192 static int netlink_sock(int *sock
, uint32_t *seq_nr
, int proto
)
199 *sock
= socket(AF_NETLINK
, SOCK_RAW
| SOCK_CLOEXEC
, proto
);
201 pr_err("socket(AF_NETLINK)");
205 randomize_buffer(seq_nr
, sizeof(*seq_nr
));
210 static inline struct rtattr
*rtattr_hdr(struct nlmsghdr
*nh
)
212 return (struct rtattr
*)((char *)(nh
) + RTA_ALIGN((nh
)->nlmsg_len
));
215 static int rtattr_pack(struct nlmsghdr
*nh
, size_t req_sz
,
216 unsigned short rta_type
, const void *payload
, size_t size
)
218 /* NLMSG_ALIGNTO == RTA_ALIGNTO, nlmsg_len already aligned */
219 struct rtattr
*attr
= rtattr_hdr(nh
);
220 size_t nl_size
= RTA_ALIGN(nh
->nlmsg_len
) + RTA_LENGTH(size
);
222 if (req_sz
< nl_size
) {
223 printk("req buf is too small: %zu < %zu", req_sz
, nl_size
);
226 nh
->nlmsg_len
= nl_size
;
228 attr
->rta_len
= RTA_LENGTH(size
);
229 attr
->rta_type
= rta_type
;
230 memcpy(RTA_DATA(attr
), payload
, size
);
235 static struct rtattr
*_rtattr_begin(struct nlmsghdr
*nh
, size_t req_sz
,
236 unsigned short rta_type
, const void *payload
, size_t size
)
238 struct rtattr
*ret
= rtattr_hdr(nh
);
240 if (rtattr_pack(nh
, req_sz
, rta_type
, payload
, size
))
246 static inline struct rtattr
*rtattr_begin(struct nlmsghdr
*nh
, size_t req_sz
,
247 unsigned short rta_type
)
249 return _rtattr_begin(nh
, req_sz
, rta_type
, 0, 0);
252 static inline void rtattr_end(struct nlmsghdr
*nh
, struct rtattr
*attr
)
254 char *nlmsg_end
= (char *)nh
+ nh
->nlmsg_len
;
256 attr
->rta_len
= nlmsg_end
- (char *)attr
;
259 static int veth_pack_peerb(struct nlmsghdr
*nh
, size_t req_sz
,
260 const char *peer
, int ns
)
263 struct rtattr
*peer_attr
;
265 memset(&pi
, 0, sizeof(pi
));
266 pi
.ifi_family
= AF_UNSPEC
;
267 pi
.ifi_change
= 0xFFFFFFFF;
269 peer_attr
= _rtattr_begin(nh
, req_sz
, VETH_INFO_PEER
, &pi
, sizeof(pi
));
273 if (rtattr_pack(nh
, req_sz
, IFLA_IFNAME
, peer
, strlen(peer
)))
276 if (rtattr_pack(nh
, req_sz
, IFLA_NET_NS_FD
, &ns
, sizeof(ns
)))
279 rtattr_end(nh
, peer_attr
);
284 static int netlink_check_answer(int sock
)
289 struct nlmsghdr orig_msg
;
292 if (recv(sock
, &answer
, sizeof(answer
), 0) < 0) {
295 } else if (answer
.hdr
.nlmsg_type
!= NLMSG_ERROR
) {
296 printk("expected NLMSG_ERROR, got %d", (int)answer
.hdr
.nlmsg_type
);
298 } else if (answer
.error
) {
299 printk("NLMSG_ERROR: %d: %s",
300 answer
.error
, strerror(-answer
.error
));
307 static int veth_add(int sock
, uint32_t seq
, const char *peera
, int ns_a
,
308 const char *peerb
, int ns_b
)
310 uint16_t flags
= NLM_F_REQUEST
| NLM_F_ACK
| NLM_F_EXCL
| NLM_F_CREATE
;
313 struct ifinfomsg info
;
314 char attrbuf
[MAX_PAYLOAD
];
316 const char veth_type
[] = "veth";
317 struct rtattr
*link_info
, *info_data
;
319 memset(&req
, 0, sizeof(req
));
320 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.info
));
321 req
.nh
.nlmsg_type
= RTM_NEWLINK
;
322 req
.nh
.nlmsg_flags
= flags
;
323 req
.nh
.nlmsg_seq
= seq
;
324 req
.info
.ifi_family
= AF_UNSPEC
;
325 req
.info
.ifi_change
= 0xFFFFFFFF;
327 if (rtattr_pack(&req
.nh
, sizeof(req
), IFLA_IFNAME
, peera
, strlen(peera
)))
330 if (rtattr_pack(&req
.nh
, sizeof(req
), IFLA_NET_NS_FD
, &ns_a
, sizeof(ns_a
)))
333 link_info
= rtattr_begin(&req
.nh
, sizeof(req
), IFLA_LINKINFO
);
337 if (rtattr_pack(&req
.nh
, sizeof(req
), IFLA_INFO_KIND
, veth_type
, sizeof(veth_type
)))
340 info_data
= rtattr_begin(&req
.nh
, sizeof(req
), IFLA_INFO_DATA
);
344 if (veth_pack_peerb(&req
.nh
, sizeof(req
), peerb
, ns_b
))
347 rtattr_end(&req
.nh
, info_data
);
348 rtattr_end(&req
.nh
, link_info
);
350 if (send(sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
354 return netlink_check_answer(sock
);
357 static int ip4_addr_set(int sock
, uint32_t seq
, const char *intf
,
358 struct in_addr addr
, uint8_t prefix
)
360 uint16_t flags
= NLM_F_REQUEST
| NLM_F_ACK
| NLM_F_EXCL
| NLM_F_CREATE
;
363 struct ifaddrmsg info
;
364 char attrbuf
[MAX_PAYLOAD
];
367 memset(&req
, 0, sizeof(req
));
368 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.info
));
369 req
.nh
.nlmsg_type
= RTM_NEWADDR
;
370 req
.nh
.nlmsg_flags
= flags
;
371 req
.nh
.nlmsg_seq
= seq
;
372 req
.info
.ifa_family
= AF_INET
;
373 req
.info
.ifa_prefixlen
= prefix
;
374 req
.info
.ifa_index
= if_nametoindex(intf
);
378 char addr_str
[IPV4_STR_SZ
] = {};
380 strncpy(addr_str
, inet_ntoa(addr
), IPV4_STR_SZ
- 1);
382 printk("ip addr set %s", addr_str
);
386 if (rtattr_pack(&req
.nh
, sizeof(req
), IFA_LOCAL
, &addr
, sizeof(addr
)))
389 if (rtattr_pack(&req
.nh
, sizeof(req
), IFA_ADDRESS
, &addr
, sizeof(addr
)))
392 if (send(sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
396 return netlink_check_answer(sock
);
399 static int link_set_up(int sock
, uint32_t seq
, const char *intf
)
403 struct ifinfomsg info
;
404 char attrbuf
[MAX_PAYLOAD
];
407 memset(&req
, 0, sizeof(req
));
408 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.info
));
409 req
.nh
.nlmsg_type
= RTM_NEWLINK
;
410 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
411 req
.nh
.nlmsg_seq
= seq
;
412 req
.info
.ifi_family
= AF_UNSPEC
;
413 req
.info
.ifi_change
= 0xFFFFFFFF;
414 req
.info
.ifi_index
= if_nametoindex(intf
);
415 req
.info
.ifi_flags
= IFF_UP
;
416 req
.info
.ifi_change
= IFF_UP
;
418 if (send(sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
422 return netlink_check_answer(sock
);
425 static int ip4_route_set(int sock
, uint32_t seq
, const char *intf
,
426 struct in_addr src
, struct in_addr dst
)
431 char attrbuf
[MAX_PAYLOAD
];
433 unsigned int index
= if_nametoindex(intf
);
435 memset(&req
, 0, sizeof(req
));
436 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.rt
));
437 req
.nh
.nlmsg_type
= RTM_NEWROUTE
;
438 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| NLM_F_CREATE
;
439 req
.nh
.nlmsg_seq
= seq
;
440 req
.rt
.rtm_family
= AF_INET
;
441 req
.rt
.rtm_dst_len
= 32;
442 req
.rt
.rtm_table
= RT_TABLE_MAIN
;
443 req
.rt
.rtm_protocol
= RTPROT_BOOT
;
444 req
.rt
.rtm_scope
= RT_SCOPE_LINK
;
445 req
.rt
.rtm_type
= RTN_UNICAST
;
447 if (rtattr_pack(&req
.nh
, sizeof(req
), RTA_DST
, &dst
, sizeof(dst
)))
450 if (rtattr_pack(&req
.nh
, sizeof(req
), RTA_PREFSRC
, &src
, sizeof(src
)))
453 if (rtattr_pack(&req
.nh
, sizeof(req
), RTA_OIF
, &index
, sizeof(index
)))
456 if (send(sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
461 return netlink_check_answer(sock
);
464 static int tunnel_set_route(int route_sock
, uint32_t *route_seq
, char *veth
,
465 struct in_addr tunsrc
, struct in_addr tundst
)
467 if (ip4_addr_set(route_sock
, (*route_seq
)++, "lo",
468 tunsrc
, PREFIX_LEN
)) {
469 printk("Failed to set ipv4 addr");
473 if (ip4_route_set(route_sock
, (*route_seq
)++, veth
, tunsrc
, tundst
)) {
474 printk("Failed to set ipv4 route");
481 static int init_child(int nsfd
, char *veth
, unsigned int src
, unsigned int dst
)
483 struct in_addr intsrc
= inet_makeaddr(INADDR_B
, src
);
484 struct in_addr tunsrc
= inet_makeaddr(INADDR_A
, src
);
485 struct in_addr tundst
= inet_makeaddr(INADDR_A
, dst
);
486 int route_sock
= -1, ret
= -1;
492 if (netlink_sock(&route_sock
, &route_seq
, NETLINK_ROUTE
)) {
493 printk("Failed to open netlink route socket in child");
497 if (ip4_addr_set(route_sock
, route_seq
++, veth
, intsrc
, PREFIX_LEN
)) {
498 printk("Failed to set ipv4 addr");
502 if (link_set_up(route_sock
, route_seq
++, veth
)) {
503 printk("Failed to bring up %s", veth
);
507 if (tunnel_set_route(route_sock
, &route_seq
, veth
, tunsrc
, tundst
)) {
508 printk("Failed to add tunnel route on %s", veth
);
527 const char *desc_name
[] = {
533 "spdinfo attributes",
539 char a_algo
[ALGO_LEN
];
540 char e_algo
[ALGO_LEN
];
541 char c_algo
[ALGO_LEN
];
542 char ae_algo
[ALGO_LEN
];
543 unsigned int icv_len
;
544 /* unsigned key_len; */
564 struct xfrm_desc xfrm_desc
;
569 struct xfrm_desc desc
;
573 static void write_test_result(unsigned int res
, struct xfrm_desc
*d
)
575 struct test_result tr
= {};
581 ret
= write(results_fd
[1], &tr
, sizeof(tr
));
582 if (ret
!= sizeof(tr
))
583 pr_err("Failed to write the result in pipe %zd", ret
);
586 static void write_msg(int fd
, struct test_desc
*msg
, bool exit_of_fail
)
588 ssize_t bytes
= write(fd
, msg
, sizeof(*msg
));
590 /* Make sure that write/read is atomic to a pipe */
591 BUILD_BUG_ON(sizeof(struct test_desc
) > PIPE_BUF
);
598 if (bytes
!= sizeof(*msg
)) {
599 pr_err("sent part of the message %zd/%zu", bytes
, sizeof(*msg
));
605 static void read_msg(int fd
, struct test_desc
*msg
, bool exit_of_fail
)
607 ssize_t bytes
= read(fd
, msg
, sizeof(*msg
));
614 if (bytes
!= sizeof(*msg
)) {
615 pr_err("got incomplete message %zd/%zu", bytes
, sizeof(*msg
));
621 static int udp_ping_init(struct in_addr listen_ip
, unsigned int u_timeout
,
622 unsigned int *server_port
, int sock
[2])
624 struct sockaddr_in server
;
625 struct timeval t
= { .tv_sec
= 0, .tv_usec
= u_timeout
};
626 socklen_t s_len
= sizeof(server
);
628 sock
[0] = socket(AF_INET
, SOCK_DGRAM
, 0);
634 server
.sin_family
= AF_INET
;
636 memcpy(&server
.sin_addr
.s_addr
, &listen_ip
, sizeof(struct in_addr
));
638 if (bind(sock
[0], (struct sockaddr
*)&server
, s_len
)) {
640 goto err_close_server
;
643 if (getsockname(sock
[0], (struct sockaddr
*)&server
, &s_len
)) {
644 pr_err("getsockname()");
645 goto err_close_server
;
648 *server_port
= ntohs(server
.sin_port
);
650 if (setsockopt(sock
[0], SOL_SOCKET
, SO_RCVTIMEO
, (const char *)&t
, sizeof t
)) {
651 pr_err("setsockopt()");
652 goto err_close_server
;
655 sock
[1] = socket(AF_INET
, SOCK_DGRAM
, 0);
658 goto err_close_server
;
668 static int udp_ping_send(int sock
[2], in_addr_t dest_ip
, unsigned int port
,
669 char *buf
, size_t buf_len
)
671 struct sockaddr_in server
;
672 const struct sockaddr
*dest_addr
= (struct sockaddr
*)&server
;
673 char *sock_buf
[buf_len
];
674 ssize_t r_bytes
, s_bytes
;
676 server
.sin_family
= AF_INET
;
677 server
.sin_port
= htons(port
);
678 server
.sin_addr
.s_addr
= dest_ip
;
680 s_bytes
= sendto(sock
[1], buf
, buf_len
, 0, dest_addr
, sizeof(server
));
684 } else if (s_bytes
!= buf_len
) {
685 printk("send part of the message: %zd/%zu", s_bytes
, sizeof(server
));
689 r_bytes
= recv(sock
[0], sock_buf
, buf_len
, 0);
694 } else if (r_bytes
== 0) { /* EOF */
695 printk("EOF on reply to ping");
697 } else if (r_bytes
!= buf_len
|| memcmp(buf
, sock_buf
, buf_len
)) {
698 printk("ping reply packet is corrupted %zd/%zu", r_bytes
, buf_len
);
705 static int udp_ping_reply(int sock
[2], in_addr_t dest_ip
, unsigned int port
,
706 char *buf
, size_t buf_len
)
708 struct sockaddr_in server
;
709 const struct sockaddr
*dest_addr
= (struct sockaddr
*)&server
;
710 char *sock_buf
[buf_len
];
711 ssize_t r_bytes
, s_bytes
;
713 server
.sin_family
= AF_INET
;
714 server
.sin_port
= htons(port
);
715 server
.sin_addr
.s_addr
= dest_ip
;
717 r_bytes
= recv(sock
[0], sock_buf
, buf_len
, 0);
723 if (r_bytes
== 0) { /* EOF */
724 printk("EOF on reply to ping");
727 if (r_bytes
!= buf_len
|| memcmp(buf
, sock_buf
, buf_len
)) {
728 printk("ping reply packet is corrupted %zd/%zu", r_bytes
, buf_len
);
732 s_bytes
= sendto(sock
[1], buf
, buf_len
, 0, dest_addr
, sizeof(server
));
736 } else if (s_bytes
!= buf_len
) {
737 printk("send part of the message: %zd/%zu", s_bytes
, sizeof(server
));
744 typedef int (*ping_f
)(int sock
[2], in_addr_t dest_ip
, unsigned int port
,
745 char *buf
, size_t buf_len
);
746 static int do_ping(int cmd_fd
, char *buf
, size_t buf_len
, struct in_addr from
,
747 bool init_side
, int d_port
, in_addr_t to
, ping_f func
)
749 struct test_desc msg
;
750 unsigned int s_port
, i
, ping_succeeded
= 0;
752 char to_str
[IPV4_STR_SZ
] = {}, from_str
[IPV4_STR_SZ
] = {};
754 if (udp_ping_init(from
, ping_timeout
, &s_port
, ping_sock
)) {
755 printk("Failed to init ping");
759 memset(&msg
, 0, sizeof(msg
));
761 msg
.body
.ping
.port
= s_port
;
762 memcpy(&msg
.body
.ping
.reply_ip
, &from
, sizeof(from
));
764 write_msg(cmd_fd
, &msg
, 0);
766 /* The other end sends ip to ping */
767 read_msg(cmd_fd
, &msg
, 0);
768 if (msg
.type
!= MSG_PING
)
770 to
= msg
.body
.ping
.reply_ip
;
771 d_port
= msg
.body
.ping
.port
;
774 for (i
= 0; i
< ping_count
; i
++) {
775 struct timespec sleep_time
= {
777 .tv_nsec
= ping_delay_nsec
,
780 ping_succeeded
+= !func(ping_sock
, to
, d_port
, buf
, page_size
);
781 nanosleep(&sleep_time
, 0);
787 strncpy(to_str
, inet_ntoa(*(struct in_addr
*)&to
), IPV4_STR_SZ
- 1);
788 strncpy(from_str
, inet_ntoa(from
), IPV4_STR_SZ
- 1);
790 if (ping_succeeded
< ping_success
) {
791 printk("ping (%s) %s->%s failed %u/%u times",
792 init_side
? "send" : "reply", from_str
, to_str
,
793 ping_count
- ping_succeeded
, ping_count
);
798 printk("ping (%s) %s->%s succeeded %u/%u times",
799 init_side
? "send" : "reply", from_str
, to_str
,
800 ping_succeeded
, ping_count
);
806 static int xfrm_fill_key(char *name
, char *buf
,
807 size_t buf_len
, unsigned int *key_len
)
811 for (i
= 0; i
< XFRM_ALGO_NR_KEYS
; i
++) {
812 if (strncmp(name
, xfrm_key_entries
[i
].algo_name
, ALGO_LEN
) == 0)
813 *key_len
= xfrm_key_entries
[i
].key_len
;
816 if (*key_len
> buf_len
) {
817 printk("Can't pack a key - too big for buffer");
821 randomize_buffer(buf
, *key_len
);
826 static int xfrm_state_pack_algo(struct nlmsghdr
*nh
, size_t req_sz
,
827 struct xfrm_desc
*desc
)
831 struct xfrm_algo alg
;
832 struct xfrm_algo_aead aead
;
833 struct xfrm_algo_auth auth
;
835 char buf
[XFRM_ALGO_KEY_BUF_SIZE
];
837 size_t alen
, elen
, clen
, aelen
;
840 alen
= strlen(desc
->a_algo
);
841 elen
= strlen(desc
->e_algo
);
842 clen
= strlen(desc
->c_algo
);
843 aelen
= strlen(desc
->ae_algo
);
846 switch (desc
->proto
) {
848 if (!alen
|| elen
|| clen
|| aelen
) {
849 printk("BUG: buggy ah desc");
852 strncpy(alg
.u
.alg
.alg_name
, desc
->a_algo
, ALGO_LEN
- 1);
853 if (xfrm_fill_key(desc
->a_algo
, alg
.u
.alg
.alg_key
,
854 sizeof(alg
.buf
), &alg
.u
.alg
.alg_key_len
))
856 type
= XFRMA_ALG_AUTH
;
859 if (!clen
|| elen
|| alen
|| aelen
) {
860 printk("BUG: buggy comp desc");
863 strncpy(alg
.u
.alg
.alg_name
, desc
->c_algo
, ALGO_LEN
- 1);
864 if (xfrm_fill_key(desc
->c_algo
, alg
.u
.alg
.alg_key
,
865 sizeof(alg
.buf
), &alg
.u
.alg
.alg_key_len
))
867 type
= XFRMA_ALG_COMP
;
870 if (!((alen
&& elen
) ^ aelen
) || clen
) {
871 printk("BUG: buggy esp desc");
875 alg
.u
.aead
.alg_icv_len
= desc
->icv_len
;
876 strncpy(alg
.u
.aead
.alg_name
, desc
->ae_algo
, ALGO_LEN
- 1);
877 if (xfrm_fill_key(desc
->ae_algo
, alg
.u
.aead
.alg_key
,
878 sizeof(alg
.buf
), &alg
.u
.aead
.alg_key_len
))
880 type
= XFRMA_ALG_AEAD
;
883 strncpy(alg
.u
.alg
.alg_name
, desc
->e_algo
, ALGO_LEN
- 1);
884 type
= XFRMA_ALG_CRYPT
;
885 if (xfrm_fill_key(desc
->e_algo
, alg
.u
.alg
.alg_key
,
886 sizeof(alg
.buf
), &alg
.u
.alg
.alg_key_len
))
888 if (rtattr_pack(nh
, req_sz
, type
, &alg
, sizeof(alg
)))
891 strncpy(alg
.u
.alg
.alg_name
, desc
->a_algo
, ALGO_LEN
);
892 type
= XFRMA_ALG_AUTH
;
893 if (xfrm_fill_key(desc
->a_algo
, alg
.u
.alg
.alg_key
,
894 sizeof(alg
.buf
), &alg
.u
.alg
.alg_key_len
))
899 printk("BUG: unknown proto in desc");
903 if (rtattr_pack(nh
, req_sz
, type
, &alg
, sizeof(alg
)))
909 static inline uint32_t gen_spi(struct in_addr src
)
911 return htonl(inet_lnaof(src
));
914 static int xfrm_state_add(int xfrm_sock
, uint32_t seq
, uint32_t spi
,
915 struct in_addr src
, struct in_addr dst
,
916 struct xfrm_desc
*desc
)
920 struct xfrm_usersa_info info
;
921 char attrbuf
[MAX_PAYLOAD
];
924 memset(&req
, 0, sizeof(req
));
925 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.info
));
926 req
.nh
.nlmsg_type
= XFRM_MSG_NEWSA
;
927 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
928 req
.nh
.nlmsg_seq
= seq
;
931 memcpy(&req
.info
.sel
.daddr
, &dst
, sizeof(dst
));
932 memcpy(&req
.info
.sel
.saddr
, &src
, sizeof(src
));
933 req
.info
.sel
.family
= AF_INET
;
934 req
.info
.sel
.prefixlen_d
= PREFIX_LEN
;
935 req
.info
.sel
.prefixlen_s
= PREFIX_LEN
;
938 memcpy(&req
.info
.id
.daddr
, &dst
, sizeof(dst
));
939 /* Note: zero-spi cannot be deleted */
940 req
.info
.id
.spi
= spi
;
941 req
.info
.id
.proto
= desc
->proto
;
943 memcpy(&req
.info
.saddr
, &src
, sizeof(src
));
945 /* Fill lifteme_cfg */
946 req
.info
.lft
.soft_byte_limit
= XFRM_INF
;
947 req
.info
.lft
.hard_byte_limit
= XFRM_INF
;
948 req
.info
.lft
.soft_packet_limit
= XFRM_INF
;
949 req
.info
.lft
.hard_packet_limit
= XFRM_INF
;
951 req
.info
.family
= AF_INET
;
952 req
.info
.mode
= XFRM_MODE_TUNNEL
;
954 if (xfrm_state_pack_algo(&req
.nh
, sizeof(req
), desc
))
957 if (send(xfrm_sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
962 return netlink_check_answer(xfrm_sock
);
965 static bool xfrm_usersa_found(struct xfrm_usersa_info
*info
, uint32_t spi
,
966 struct in_addr src
, struct in_addr dst
,
967 struct xfrm_desc
*desc
)
969 if (memcmp(&info
->sel
.daddr
, &dst
, sizeof(dst
)))
972 if (memcmp(&info
->sel
.saddr
, &src
, sizeof(src
)))
975 if (info
->sel
.family
!= AF_INET
||
976 info
->sel
.prefixlen_d
!= PREFIX_LEN
||
977 info
->sel
.prefixlen_s
!= PREFIX_LEN
)
980 if (info
->id
.spi
!= spi
|| info
->id
.proto
!= desc
->proto
)
983 if (memcmp(&info
->id
.daddr
, &dst
, sizeof(dst
)))
986 if (memcmp(&info
->saddr
, &src
, sizeof(src
)))
989 if (info
->lft
.soft_byte_limit
!= XFRM_INF
||
990 info
->lft
.hard_byte_limit
!= XFRM_INF
||
991 info
->lft
.soft_packet_limit
!= XFRM_INF
||
992 info
->lft
.hard_packet_limit
!= XFRM_INF
)
995 if (info
->family
!= AF_INET
|| info
->mode
!= XFRM_MODE_TUNNEL
)
998 /* XXX: check xfrm algo, see xfrm_state_pack_algo(). */
1003 static int xfrm_state_check(int xfrm_sock
, uint32_t seq
, uint32_t spi
,
1004 struct in_addr src
, struct in_addr dst
,
1005 struct xfrm_desc
*desc
)
1009 char attrbuf
[MAX_PAYLOAD
];
1014 struct xfrm_usersa_info info
;
1017 char attrbuf
[MAX_PAYLOAD
];
1019 struct xfrm_address_filter filter
= {};
1023 memset(&req
, 0, sizeof(req
));
1024 req
.nh
.nlmsg_len
= NLMSG_LENGTH(0);
1025 req
.nh
.nlmsg_type
= XFRM_MSG_GETSA
;
1026 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_DUMP
;
1027 req
.nh
.nlmsg_seq
= seq
;
1030 * Add dump filter by source address as there may be other tunnels
1031 * in this netns (if tests run in parallel).
1033 filter
.family
= AF_INET
;
1034 filter
.splen
= 0x1f; /* 0xffffffff mask see addr_match() */
1035 memcpy(&filter
.saddr
, &src
, sizeof(src
));
1036 if (rtattr_pack(&req
.nh
, sizeof(req
), XFRMA_ADDRESS_FILTER
,
1037 &filter
, sizeof(filter
)))
1040 if (send(xfrm_sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
1046 if (recv(xfrm_sock
, &answer
, sizeof(answer
), 0) < 0) {
1050 if (answer
.nh
.nlmsg_type
== NLMSG_ERROR
) {
1051 printk("NLMSG_ERROR: %d: %s",
1052 answer
.error
, strerror(-answer
.error
));
1054 } else if (answer
.nh
.nlmsg_type
== NLMSG_DONE
) {
1057 printk("didn't find allocated xfrm state in dump");
1059 } else if (answer
.nh
.nlmsg_type
== XFRM_MSG_NEWSA
) {
1060 if (xfrm_usersa_found(&answer
.info
, spi
, src
, dst
, desc
))
1066 static int xfrm_set(int xfrm_sock
, uint32_t *seq
,
1067 struct in_addr src
, struct in_addr dst
,
1068 struct in_addr tunsrc
, struct in_addr tundst
,
1069 struct xfrm_desc
*desc
)
1073 err
= xfrm_state_add(xfrm_sock
, (*seq
)++, gen_spi(src
), src
, dst
, desc
);
1075 printk("Failed to add xfrm state");
1079 err
= xfrm_state_add(xfrm_sock
, (*seq
)++, gen_spi(src
), dst
, src
, desc
);
1081 printk("Failed to add xfrm state");
1085 /* Check dumps for XFRM_MSG_GETSA */
1086 err
= xfrm_state_check(xfrm_sock
, (*seq
)++, gen_spi(src
), src
, dst
, desc
);
1087 err
|= xfrm_state_check(xfrm_sock
, (*seq
)++, gen_spi(src
), dst
, src
, desc
);
1089 printk("Failed to check xfrm state");
1096 static int xfrm_policy_add(int xfrm_sock
, uint32_t seq
, uint32_t spi
,
1097 struct in_addr src
, struct in_addr dst
, uint8_t dir
,
1098 struct in_addr tunsrc
, struct in_addr tundst
, uint8_t proto
)
1102 struct xfrm_userpolicy_info info
;
1103 char attrbuf
[MAX_PAYLOAD
];
1105 struct xfrm_user_tmpl tmpl
;
1107 memset(&req
, 0, sizeof(req
));
1108 memset(&tmpl
, 0, sizeof(tmpl
));
1109 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.info
));
1110 req
.nh
.nlmsg_type
= XFRM_MSG_NEWPOLICY
;
1111 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1112 req
.nh
.nlmsg_seq
= seq
;
1114 /* Fill selector. */
1115 memcpy(&req
.info
.sel
.daddr
, &dst
, sizeof(tundst
));
1116 memcpy(&req
.info
.sel
.saddr
, &src
, sizeof(tunsrc
));
1117 req
.info
.sel
.family
= AF_INET
;
1118 req
.info
.sel
.prefixlen_d
= PREFIX_LEN
;
1119 req
.info
.sel
.prefixlen_s
= PREFIX_LEN
;
1121 /* Fill lifteme_cfg */
1122 req
.info
.lft
.soft_byte_limit
= XFRM_INF
;
1123 req
.info
.lft
.hard_byte_limit
= XFRM_INF
;
1124 req
.info
.lft
.soft_packet_limit
= XFRM_INF
;
1125 req
.info
.lft
.hard_packet_limit
= XFRM_INF
;
1130 memcpy(&tmpl
.id
.daddr
, &dst
, sizeof(dst
));
1131 /* Note: zero-spi cannot be deleted */
1133 tmpl
.id
.proto
= proto
;
1134 tmpl
.family
= AF_INET
;
1135 memcpy(&tmpl
.saddr
, &src
, sizeof(src
));
1136 tmpl
.mode
= XFRM_MODE_TUNNEL
;
1137 tmpl
.aalgos
= (~(uint32_t)0);
1138 tmpl
.ealgos
= (~(uint32_t)0);
1139 tmpl
.calgos
= (~(uint32_t)0);
1141 if (rtattr_pack(&req
.nh
, sizeof(req
), XFRMA_TMPL
, &tmpl
, sizeof(tmpl
)))
1144 if (send(xfrm_sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
1149 return netlink_check_answer(xfrm_sock
);
1152 static int xfrm_prepare(int xfrm_sock
, uint32_t *seq
,
1153 struct in_addr src
, struct in_addr dst
,
1154 struct in_addr tunsrc
, struct in_addr tundst
, uint8_t proto
)
1156 if (xfrm_policy_add(xfrm_sock
, (*seq
)++, gen_spi(src
), src
, dst
,
1157 XFRM_POLICY_OUT
, tunsrc
, tundst
, proto
)) {
1158 printk("Failed to add xfrm policy");
1162 if (xfrm_policy_add(xfrm_sock
, (*seq
)++, gen_spi(src
), dst
, src
,
1163 XFRM_POLICY_IN
, tunsrc
, tundst
, proto
)) {
1164 printk("Failed to add xfrm policy");
1171 static int xfrm_policy_del(int xfrm_sock
, uint32_t seq
,
1172 struct in_addr src
, struct in_addr dst
, uint8_t dir
,
1173 struct in_addr tunsrc
, struct in_addr tundst
)
1177 struct xfrm_userpolicy_id id
;
1178 char attrbuf
[MAX_PAYLOAD
];
1181 memset(&req
, 0, sizeof(req
));
1182 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.id
));
1183 req
.nh
.nlmsg_type
= XFRM_MSG_DELPOLICY
;
1184 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1185 req
.nh
.nlmsg_seq
= seq
;
1188 memcpy(&req
.id
.sel
.daddr
, &dst
, sizeof(tundst
));
1189 memcpy(&req
.id
.sel
.saddr
, &src
, sizeof(tunsrc
));
1190 req
.id
.sel
.family
= AF_INET
;
1191 req
.id
.sel
.prefixlen_d
= PREFIX_LEN
;
1192 req
.id
.sel
.prefixlen_s
= PREFIX_LEN
;
1195 if (send(xfrm_sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
1200 return netlink_check_answer(xfrm_sock
);
1203 static int xfrm_cleanup(int xfrm_sock
, uint32_t *seq
,
1204 struct in_addr src
, struct in_addr dst
,
1205 struct in_addr tunsrc
, struct in_addr tundst
)
1207 if (xfrm_policy_del(xfrm_sock
, (*seq
)++, src
, dst
,
1208 XFRM_POLICY_OUT
, tunsrc
, tundst
)) {
1209 printk("Failed to add xfrm policy");
1213 if (xfrm_policy_del(xfrm_sock
, (*seq
)++, dst
, src
,
1214 XFRM_POLICY_IN
, tunsrc
, tundst
)) {
1215 printk("Failed to add xfrm policy");
1222 static int xfrm_state_del(int xfrm_sock
, uint32_t seq
, uint32_t spi
,
1223 struct in_addr src
, struct in_addr dst
, uint8_t proto
)
1227 struct xfrm_usersa_id id
;
1228 char attrbuf
[MAX_PAYLOAD
];
1230 xfrm_address_t saddr
= {};
1232 memset(&req
, 0, sizeof(req
));
1233 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.id
));
1234 req
.nh
.nlmsg_type
= XFRM_MSG_DELSA
;
1235 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1236 req
.nh
.nlmsg_seq
= seq
;
1238 memcpy(&req
.id
.daddr
, &dst
, sizeof(dst
));
1239 req
.id
.family
= AF_INET
;
1240 req
.id
.proto
= proto
;
1241 /* Note: zero-spi cannot be deleted */
1244 memcpy(&saddr
, &src
, sizeof(src
));
1245 if (rtattr_pack(&req
.nh
, sizeof(req
), XFRMA_SRCADDR
, &saddr
, sizeof(saddr
)))
1248 if (send(xfrm_sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
1253 return netlink_check_answer(xfrm_sock
);
1256 static int xfrm_delete(int xfrm_sock
, uint32_t *seq
,
1257 struct in_addr src
, struct in_addr dst
,
1258 struct in_addr tunsrc
, struct in_addr tundst
, uint8_t proto
)
1260 if (xfrm_state_del(xfrm_sock
, (*seq
)++, gen_spi(src
), src
, dst
, proto
)) {
1261 printk("Failed to remove xfrm state");
1265 if (xfrm_state_del(xfrm_sock
, (*seq
)++, gen_spi(src
), dst
, src
, proto
)) {
1266 printk("Failed to remove xfrm state");
1273 static int xfrm_state_allocspi(int xfrm_sock
, uint32_t *seq
,
1274 uint32_t spi
, uint8_t proto
)
1278 struct xfrm_userspi_info spi
;
1283 struct xfrm_usersa_info info
;
1288 memset(&req
, 0, sizeof(req
));
1289 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.spi
));
1290 req
.nh
.nlmsg_type
= XFRM_MSG_ALLOCSPI
;
1291 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
;
1292 req
.nh
.nlmsg_seq
= (*seq
)++;
1294 req
.spi
.info
.family
= AF_INET
;
1297 req
.spi
.info
.id
.proto
= proto
;
1299 if (send(xfrm_sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
1304 if (recv(xfrm_sock
, &answer
, sizeof(answer
), 0) < 0) {
1307 } else if (answer
.nh
.nlmsg_type
== XFRM_MSG_NEWSA
) {
1308 uint32_t new_spi
= htonl(answer
.info
.id
.spi
);
1310 if (new_spi
!= spi
) {
1311 printk("allocated spi is different from requested: %#x != %#x",
1316 } else if (answer
.nh
.nlmsg_type
!= NLMSG_ERROR
) {
1317 printk("expected NLMSG_ERROR, got %d", (int)answer
.nh
.nlmsg_type
);
1321 printk("NLMSG_ERROR: %d: %s", answer
.error
, strerror(-answer
.error
));
1322 return (answer
.error
) ? KSFT_FAIL
: KSFT_PASS
;
1325 static int netlink_sock_bind(int *sock
, uint32_t *seq
, int proto
, uint32_t groups
)
1327 struct sockaddr_nl snl
= {};
1331 snl
.nl_family
= AF_NETLINK
;
1332 snl
.nl_groups
= groups
;
1334 if (netlink_sock(sock
, seq
, proto
)) {
1335 printk("Failed to open xfrm netlink socket");
1339 if (bind(*sock
, (struct sockaddr
*)&snl
, sizeof(snl
)) < 0) {
1344 addr_len
= sizeof(snl
);
1345 if (getsockname(*sock
, (struct sockaddr
*)&snl
, &addr_len
) < 0) {
1346 pr_err("getsockname()");
1349 if (addr_len
!= sizeof(snl
)) {
1350 printk("Wrong address length %d", addr_len
);
1353 if (snl
.nl_family
!= AF_NETLINK
) {
1354 printk("Wrong address family %d", snl
.nl_family
);
1364 static int xfrm_monitor_acquire(int xfrm_sock
, uint32_t *seq
, unsigned int nr
)
1369 struct xfrm_user_acquire acq
;
1372 char attrbuf
[MAX_PAYLOAD
];
1374 struct xfrm_user_tmpl xfrm_tmpl
= {};
1375 int xfrm_listen
= -1, ret
= KSFT_FAIL
;
1376 uint32_t seq_listen
;
1378 if (netlink_sock_bind(&xfrm_listen
, &seq_listen
, NETLINK_XFRM
, XFRMNLGRP_ACQUIRE
))
1381 memset(&req
, 0, sizeof(req
));
1382 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.acq
));
1383 req
.nh
.nlmsg_type
= XFRM_MSG_ACQUIRE
;
1384 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1385 req
.nh
.nlmsg_seq
= (*seq
)++;
1387 req
.acq
.policy
.sel
.family
= AF_INET
;
1388 req
.acq
.aalgos
= 0xfeed;
1389 req
.acq
.ealgos
= 0xbaad;
1390 req
.acq
.calgos
= 0xbabe;
1392 xfrm_tmpl
.family
= AF_INET
;
1393 xfrm_tmpl
.id
.proto
= IPPROTO_ESP
;
1394 if (rtattr_pack(&req
.nh
, sizeof(req
), XFRMA_TMPL
, &xfrm_tmpl
, sizeof(xfrm_tmpl
)))
1397 if (send(xfrm_sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
1402 if (recv(xfrm_sock
, &req
, sizeof(req
), 0) < 0) {
1405 } else if (req
.nh
.nlmsg_type
!= NLMSG_ERROR
) {
1406 printk("expected NLMSG_ERROR, got %d", (int)req
.nh
.nlmsg_type
);
1411 printk("NLMSG_ERROR: %d: %s", req
.error
, strerror(-req
.error
));
1416 if (recv(xfrm_listen
, &req
, sizeof(req
), 0) < 0) {
1421 if (req
.acq
.aalgos
!= 0xfeed || req
.acq
.ealgos
!= 0xbaad
1422 || req
.acq
.calgos
!= 0xbabe) {
1423 printk("xfrm_user_acquire has changed %x %x %x",
1424 req
.acq
.aalgos
, req
.acq
.ealgos
, req
.acq
.calgos
);
1434 static int xfrm_expire_state(int xfrm_sock
, uint32_t *seq
,
1435 unsigned int nr
, struct xfrm_desc
*desc
)
1440 struct xfrm_user_expire expire
;
1444 struct in_addr src
, dst
;
1445 int xfrm_listen
= -1, ret
= KSFT_FAIL
;
1446 uint32_t seq_listen
;
1448 src
= inet_makeaddr(INADDR_B
, child_ip(nr
));
1449 dst
= inet_makeaddr(INADDR_B
, grchild_ip(nr
));
1451 if (xfrm_state_add(xfrm_sock
, (*seq
)++, gen_spi(src
), src
, dst
, desc
)) {
1452 printk("Failed to add xfrm state");
1456 if (netlink_sock_bind(&xfrm_listen
, &seq_listen
, NETLINK_XFRM
, XFRMNLGRP_EXPIRE
))
1459 memset(&req
, 0, sizeof(req
));
1460 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.expire
));
1461 req
.nh
.nlmsg_type
= XFRM_MSG_EXPIRE
;
1462 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1463 req
.nh
.nlmsg_seq
= (*seq
)++;
1465 memcpy(&req
.expire
.state
.id
.daddr
, &dst
, sizeof(dst
));
1466 req
.expire
.state
.id
.spi
= gen_spi(src
);
1467 req
.expire
.state
.id
.proto
= desc
->proto
;
1468 req
.expire
.state
.family
= AF_INET
;
1469 req
.expire
.hard
= 0xff;
1471 if (send(xfrm_sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
1476 if (recv(xfrm_sock
, &req
, sizeof(req
), 0) < 0) {
1479 } else if (req
.nh
.nlmsg_type
!= NLMSG_ERROR
) {
1480 printk("expected NLMSG_ERROR, got %d", (int)req
.nh
.nlmsg_type
);
1485 printk("NLMSG_ERROR: %d: %s", req
.error
, strerror(-req
.error
));
1490 if (recv(xfrm_listen
, &req
, sizeof(req
), 0) < 0) {
1495 if (req
.expire
.hard
!= 0x1) {
1496 printk("expire.hard is not set: %x", req
.expire
.hard
);
1506 static int xfrm_expire_policy(int xfrm_sock
, uint32_t *seq
,
1507 unsigned int nr
, struct xfrm_desc
*desc
)
1512 struct xfrm_user_polexpire expire
;
1516 struct in_addr src
, dst
, tunsrc
, tundst
;
1517 int xfrm_listen
= -1, ret
= KSFT_FAIL
;
1518 uint32_t seq_listen
;
1520 src
= inet_makeaddr(INADDR_B
, child_ip(nr
));
1521 dst
= inet_makeaddr(INADDR_B
, grchild_ip(nr
));
1522 tunsrc
= inet_makeaddr(INADDR_A
, child_ip(nr
));
1523 tundst
= inet_makeaddr(INADDR_A
, grchild_ip(nr
));
1525 if (xfrm_policy_add(xfrm_sock
, (*seq
)++, gen_spi(src
), src
, dst
,
1526 XFRM_POLICY_OUT
, tunsrc
, tundst
, desc
->proto
)) {
1527 printk("Failed to add xfrm policy");
1531 if (netlink_sock_bind(&xfrm_listen
, &seq_listen
, NETLINK_XFRM
, XFRMNLGRP_EXPIRE
))
1534 memset(&req
, 0, sizeof(req
));
1535 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.expire
));
1536 req
.nh
.nlmsg_type
= XFRM_MSG_POLEXPIRE
;
1537 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1538 req
.nh
.nlmsg_seq
= (*seq
)++;
1540 /* Fill selector. */
1541 memcpy(&req
.expire
.pol
.sel
.daddr
, &dst
, sizeof(tundst
));
1542 memcpy(&req
.expire
.pol
.sel
.saddr
, &src
, sizeof(tunsrc
));
1543 req
.expire
.pol
.sel
.family
= AF_INET
;
1544 req
.expire
.pol
.sel
.prefixlen_d
= PREFIX_LEN
;
1545 req
.expire
.pol
.sel
.prefixlen_s
= PREFIX_LEN
;
1546 req
.expire
.pol
.dir
= XFRM_POLICY_OUT
;
1547 req
.expire
.hard
= 0xff;
1549 if (send(xfrm_sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
1554 if (recv(xfrm_sock
, &req
, sizeof(req
), 0) < 0) {
1557 } else if (req
.nh
.nlmsg_type
!= NLMSG_ERROR
) {
1558 printk("expected NLMSG_ERROR, got %d", (int)req
.nh
.nlmsg_type
);
1563 printk("NLMSG_ERROR: %d: %s", req
.error
, strerror(-req
.error
));
1568 if (recv(xfrm_listen
, &req
, sizeof(req
), 0) < 0) {
1573 if (req
.expire
.hard
!= 0x1) {
1574 printk("expire.hard is not set: %x", req
.expire
.hard
);
1584 static int xfrm_spdinfo_set_thresh(int xfrm_sock
, uint32_t *seq
,
1585 unsigned thresh4_l
, unsigned thresh4_r
,
1586 unsigned thresh6_l
, unsigned thresh6_r
,
1596 char attrbuf
[MAX_PAYLOAD
];
1598 struct xfrmu_spdhthresh thresh
;
1600 memset(&req
, 0, sizeof(req
));
1601 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.unused
));
1602 req
.nh
.nlmsg_type
= XFRM_MSG_NEWSPDINFO
;
1603 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1604 req
.nh
.nlmsg_seq
= (*seq
)++;
1606 thresh
.lbits
= thresh4_l
;
1607 thresh
.rbits
= thresh4_r
;
1608 if (rtattr_pack(&req
.nh
, sizeof(req
), XFRMA_SPD_IPV4_HTHRESH
, &thresh
, sizeof(thresh
)))
1611 thresh
.lbits
= thresh6_l
;
1612 thresh
.rbits
= thresh6_r
;
1613 if (rtattr_pack(&req
.nh
, sizeof(req
), XFRMA_SPD_IPV6_HTHRESH
, &thresh
, sizeof(thresh
)))
1617 BUILD_BUG_ON(XFRMA_IF_ID
<= XFRMA_SPD_MAX
+ 1);
1618 if (rtattr_pack(&req
.nh
, sizeof(req
), XFRMA_IF_ID
, NULL
, 0)) {
1619 pr_err("adding attribute failed: no space");
1624 if (send(xfrm_sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
1629 if (recv(xfrm_sock
, &req
, sizeof(req
), 0) < 0) {
1632 } else if (req
.nh
.nlmsg_type
!= NLMSG_ERROR
) {
1633 printk("expected NLMSG_ERROR, got %d", (int)req
.nh
.nlmsg_type
);
1638 printk("NLMSG_ERROR: %d: %s", req
.error
, strerror(-req
.error
));
1645 static int xfrm_spdinfo_attrs(int xfrm_sock
, uint32_t *seq
)
1653 char attrbuf
[MAX_PAYLOAD
];
1656 if (xfrm_spdinfo_set_thresh(xfrm_sock
, seq
, 32, 31, 120, 16, false)) {
1657 pr_err("Can't set SPD HTHRESH");
1661 memset(&req
, 0, sizeof(req
));
1663 req
.nh
.nlmsg_len
= NLMSG_LENGTH(sizeof(req
.unused
));
1664 req
.nh
.nlmsg_type
= XFRM_MSG_GETSPDINFO
;
1665 req
.nh
.nlmsg_flags
= NLM_F_REQUEST
;
1666 req
.nh
.nlmsg_seq
= (*seq
)++;
1667 if (send(xfrm_sock
, &req
, req
.nh
.nlmsg_len
, 0) < 0) {
1672 if (recv(xfrm_sock
, &req
, sizeof(req
), 0) < 0) {
1675 } else if (req
.nh
.nlmsg_type
== XFRM_MSG_NEWSPDINFO
) {
1676 size_t len
= NLMSG_PAYLOAD(&req
.nh
, sizeof(req
.unused
));
1677 struct rtattr
*attr
= (void *)req
.attrbuf
;
1680 for (; RTA_OK(attr
, len
); attr
= RTA_NEXT(attr
, len
)) {
1681 if (attr
->rta_type
== XFRMA_SPD_IPV4_HTHRESH
) {
1682 struct xfrmu_spdhthresh
*t
= RTA_DATA(attr
);
1685 if (t
->lbits
!= 32 || t
->rbits
!= 31) {
1686 pr_err("thresh differ: %u, %u",
1687 t
->lbits
, t
->rbits
);
1691 if (attr
->rta_type
== XFRMA_SPD_IPV6_HTHRESH
) {
1692 struct xfrmu_spdhthresh
*t
= RTA_DATA(attr
);
1695 if (t
->lbits
!= 120 || t
->rbits
!= 16) {
1696 pr_err("thresh differ: %u, %u",
1697 t
->lbits
, t
->rbits
);
1702 if (got_thresh
!= 2) {
1703 pr_err("only %d thresh returned by XFRM_MSG_GETSPDINFO", got_thresh
);
1706 } else if (req
.nh
.nlmsg_type
!= NLMSG_ERROR
) {
1707 printk("expected NLMSG_ERROR, got %d", (int)req
.nh
.nlmsg_type
);
1710 printk("NLMSG_ERROR: %d: %s", req
.error
, strerror(-req
.error
));
1714 /* Restore the default */
1715 if (xfrm_spdinfo_set_thresh(xfrm_sock
, seq
, 32, 32, 128, 128, false)) {
1716 pr_err("Can't restore SPD HTHRESH");
1721 * At this moment xfrm uses nlmsg_parse_deprecated(), which
1722 * implies NL_VALIDATE_LIBERAL - ignoring attributes with
1723 * (type > maxtype). nla_parse_depricated_strict() would enforce
1724 * it. Or even stricter nla_parse().
1725 * Right now it's not expected to fail, but to be ignored.
1727 if (xfrm_spdinfo_set_thresh(xfrm_sock
, seq
, 32, 32, 128, 128, true))
1733 static int child_serv(int xfrm_sock
, uint32_t *seq
,
1734 unsigned int nr
, int cmd_fd
, void *buf
, struct xfrm_desc
*desc
)
1736 struct in_addr src
, dst
, tunsrc
, tundst
;
1737 struct test_desc msg
;
1738 int ret
= KSFT_FAIL
;
1740 src
= inet_makeaddr(INADDR_B
, child_ip(nr
));
1741 dst
= inet_makeaddr(INADDR_B
, grchild_ip(nr
));
1742 tunsrc
= inet_makeaddr(INADDR_A
, child_ip(nr
));
1743 tundst
= inet_makeaddr(INADDR_A
, grchild_ip(nr
));
1745 /* UDP pinging without xfrm */
1746 if (do_ping(cmd_fd
, buf
, page_size
, src
, true, 0, 0, udp_ping_send
)) {
1747 printk("ping failed before setting xfrm");
1751 memset(&msg
, 0, sizeof(msg
));
1752 msg
.type
= MSG_XFRM_PREPARE
;
1753 memcpy(&msg
.body
.xfrm_desc
, desc
, sizeof(*desc
));
1754 write_msg(cmd_fd
, &msg
, 1);
1756 if (xfrm_prepare(xfrm_sock
, seq
, src
, dst
, tunsrc
, tundst
, desc
->proto
)) {
1757 printk("failed to prepare xfrm");
1761 memset(&msg
, 0, sizeof(msg
));
1762 msg
.type
= MSG_XFRM_ADD
;
1763 memcpy(&msg
.body
.xfrm_desc
, desc
, sizeof(*desc
));
1764 write_msg(cmd_fd
, &msg
, 1);
1765 if (xfrm_set(xfrm_sock
, seq
, src
, dst
, tunsrc
, tundst
, desc
)) {
1766 printk("failed to set xfrm");
1770 /* UDP pinging with xfrm tunnel */
1771 if (do_ping(cmd_fd
, buf
, page_size
, tunsrc
,
1772 true, 0, 0, udp_ping_send
)) {
1773 printk("ping failed for xfrm");
1780 memset(&msg
, 0, sizeof(msg
));
1781 msg
.type
= MSG_XFRM_DEL
;
1782 memcpy(&msg
.body
.xfrm_desc
, desc
, sizeof(*desc
));
1783 write_msg(cmd_fd
, &msg
, 1);
1785 if (xfrm_delete(xfrm_sock
, seq
, src
, dst
, tunsrc
, tundst
, desc
->proto
)) {
1786 printk("failed ping to remove xfrm");
1791 memset(&msg
, 0, sizeof(msg
));
1792 msg
.type
= MSG_XFRM_CLEANUP
;
1793 memcpy(&msg
.body
.xfrm_desc
, desc
, sizeof(*desc
));
1794 write_msg(cmd_fd
, &msg
, 1);
1795 if (xfrm_cleanup(xfrm_sock
, seq
, src
, dst
, tunsrc
, tundst
)) {
1796 printk("failed ping to cleanup xfrm");
1802 static int child_f(unsigned int nr
, int test_desc_fd
, int cmd_fd
, void *buf
)
1804 struct xfrm_desc desc
;
1805 struct test_desc msg
;
1809 if (switch_ns(nsfd_childa
))
1812 if (netlink_sock(&xfrm_sock
, &seq
, NETLINK_XFRM
)) {
1813 printk("Failed to open xfrm netlink socket");
1817 /* Check that seq sock is ready, just for sure. */
1818 memset(&msg
, 0, sizeof(msg
));
1820 write_msg(cmd_fd
, &msg
, 1);
1821 read_msg(cmd_fd
, &msg
, 1);
1822 if (msg
.type
!= MSG_ACK
) {
1823 printk("Ack failed");
1828 ssize_t received
= read(test_desc_fd
, &desc
, sizeof(desc
));
1831 if (received
== 0) /* EOF */
1834 if (received
!= sizeof(desc
)) {
1835 pr_err("read() returned %zd", received
);
1839 switch (desc
.type
) {
1841 ret
= child_serv(xfrm_sock
, &seq
, nr
,
1842 cmd_fd
, buf
, &desc
);
1845 ret
= xfrm_state_allocspi(xfrm_sock
, &seq
,
1848 case MONITOR_ACQUIRE
:
1849 ret
= xfrm_monitor_acquire(xfrm_sock
, &seq
, nr
);
1852 ret
= xfrm_expire_state(xfrm_sock
, &seq
, nr
, &desc
);
1855 ret
= xfrm_expire_policy(xfrm_sock
, &seq
, nr
, &desc
);
1858 ret
= xfrm_spdinfo_attrs(xfrm_sock
, &seq
);
1861 printk("Unknown desc type %d", desc
.type
);
1864 write_test_result(ret
, &desc
);
1869 msg
.type
= MSG_EXIT
;
1870 write_msg(cmd_fd
, &msg
, 1);
1874 static void grand_child_serv(unsigned int nr
, int cmd_fd
, void *buf
,
1875 struct test_desc
*msg
, int xfrm_sock
, uint32_t *seq
)
1877 struct in_addr src
, dst
, tunsrc
, tundst
;
1879 struct xfrm_desc
*desc
= &msg
->body
.xfrm_desc
;
1881 src
= inet_makeaddr(INADDR_B
, grchild_ip(nr
));
1882 dst
= inet_makeaddr(INADDR_B
, child_ip(nr
));
1883 tunsrc
= inet_makeaddr(INADDR_A
, grchild_ip(nr
));
1884 tundst
= inet_makeaddr(INADDR_A
, child_ip(nr
));
1886 switch (msg
->type
) {
1890 write_msg(cmd_fd
, msg
, 1);
1893 tun_reply
= memcmp(&dst
, &msg
->body
.ping
.reply_ip
, sizeof(in_addr_t
));
1894 /* UDP pinging without xfrm */
1895 if (do_ping(cmd_fd
, buf
, page_size
, tun_reply
? tunsrc
: src
,
1896 false, msg
->body
.ping
.port
,
1897 msg
->body
.ping
.reply_ip
, udp_ping_reply
)) {
1898 printk("ping failed before setting xfrm");
1901 case MSG_XFRM_PREPARE
:
1902 if (xfrm_prepare(xfrm_sock
, seq
, src
, dst
, tunsrc
, tundst
,
1904 xfrm_cleanup(xfrm_sock
, seq
, src
, dst
, tunsrc
, tundst
);
1905 printk("failed to prepare xfrm");
1909 if (xfrm_set(xfrm_sock
, seq
, src
, dst
, tunsrc
, tundst
, desc
)) {
1910 xfrm_cleanup(xfrm_sock
, seq
, src
, dst
, tunsrc
, tundst
);
1911 printk("failed to set xfrm");
1915 if (xfrm_delete(xfrm_sock
, seq
, src
, dst
, tunsrc
, tundst
,
1917 xfrm_cleanup(xfrm_sock
, seq
, src
, dst
, tunsrc
, tundst
);
1918 printk("failed to remove xfrm");
1921 case MSG_XFRM_CLEANUP
:
1922 if (xfrm_cleanup(xfrm_sock
, seq
, src
, dst
, tunsrc
, tundst
)) {
1923 printk("failed to cleanup xfrm");
1927 printk("got unknown msg type %d", msg
->type
);
1931 static int grand_child_f(unsigned int nr
, int cmd_fd
, void *buf
)
1933 struct test_desc msg
;
1937 if (switch_ns(nsfd_childb
))
1940 if (netlink_sock(&xfrm_sock
, &seq
, NETLINK_XFRM
)) {
1941 printk("Failed to open xfrm netlink socket");
1946 read_msg(cmd_fd
, &msg
, 1);
1947 grand_child_serv(nr
, cmd_fd
, buf
, &msg
, xfrm_sock
, &seq
);
1954 static int start_child(unsigned int nr
, char *veth
, int test_desc_fd
[2])
1960 if (init_child(nsfd_childa
, veth
, child_ip(nr
), grchild_ip(nr
)))
1963 if (init_child(nsfd_childb
, veth
, grchild_ip(nr
), child_ip(nr
)))
1971 /* in parent - selftest */
1972 return switch_ns(nsfd_parent
);
1975 if (close(test_desc_fd
[1])) {
1981 data_map
= mmap(0, page_size
, PROT_READ
| PROT_WRITE
,
1982 MAP_SHARED
| MAP_ANONYMOUS
, -1, 0);
1983 if (data_map
== MAP_FAILED
) {
1988 randomize_buffer(data_map
, page_size
);
1990 if (socketpair(PF_LOCAL
, SOCK_SEQPACKET
, 0, cmd_sock
)) {
1991 pr_err("socketpair()");
2000 if (close(cmd_sock
[0])) {
2004 return child_f(nr
, test_desc_fd
[0], cmd_sock
[1], data_map
);
2006 if (close(cmd_sock
[1])) {
2010 return grand_child_f(nr
, cmd_sock
[0], data_map
);
2013 static void exit_usage(char **argv
)
2015 printk("Usage: %s [nr_process]", argv
[0]);
2019 static int __write_desc(int test_desc_fd
, struct xfrm_desc
*desc
)
2023 ret
= write(test_desc_fd
, desc
, sizeof(*desc
));
2025 if (ret
== sizeof(*desc
))
2028 pr_err("Writing test's desc failed %ld", ret
);
2033 static int write_desc(int proto
, int test_desc_fd
,
2034 char *a
, char *e
, char *c
, char *ae
)
2036 struct xfrm_desc desc
= {};
2038 desc
.type
= CREATE_TUNNEL
;
2042 strncpy(desc
.a_algo
, a
, ALGO_LEN
- 1);
2044 strncpy(desc
.e_algo
, e
, ALGO_LEN
- 1);
2046 strncpy(desc
.c_algo
, c
, ALGO_LEN
- 1);
2048 strncpy(desc
.ae_algo
, ae
, ALGO_LEN
- 1);
2050 return __write_desc(test_desc_fd
, &desc
);
2053 int proto_list
[] = { IPPROTO_AH
, IPPROTO_COMP
, IPPROTO_ESP
};
2055 "digest_null", "hmac(md5)", "hmac(sha1)", "hmac(sha256)",
2056 "hmac(sha384)", "hmac(sha512)", "hmac(rmd160)",
2057 "xcbc(aes)", "cmac(aes)"
2059 char *comp_list
[] = {
2062 /* No compression backend realization */
2067 "ecb(cipher_null)", "cbc(des)", "cbc(des3_ede)", "cbc(cast5)",
2068 "cbc(blowfish)", "cbc(aes)", "cbc(serpent)", "cbc(camellia)",
2069 "cbc(twofish)", "rfc3686(ctr(aes))"
2073 /* not implemented */
2074 "rfc4106(gcm(aes))", "rfc4309(ccm(aes))", "rfc4543(gcm(aes))",
2075 "rfc7539esp(chacha20,poly1305)"
2079 const unsigned int proto_plan
= ARRAY_SIZE(ah_list
) + ARRAY_SIZE(comp_list
) \
2080 + (ARRAY_SIZE(ah_list
) * ARRAY_SIZE(e_list
)) \
2081 + ARRAY_SIZE(ae_list
);
2083 static int write_proto_plan(int fd
, int proto
)
2089 for (i
= 0; i
< ARRAY_SIZE(ah_list
); i
++) {
2090 if (write_desc(proto
, fd
, ah_list
[i
], 0, 0, 0))
2095 for (i
= 0; i
< ARRAY_SIZE(comp_list
); i
++) {
2096 if (write_desc(proto
, fd
, 0, 0, comp_list
[i
], 0))
2101 for (i
= 0; i
< ARRAY_SIZE(ah_list
); i
++) {
2104 for (j
= 0; j
< ARRAY_SIZE(e_list
); j
++) {
2105 if (write_desc(proto
, fd
, ah_list
[i
],
2110 for (i
= 0; i
< ARRAY_SIZE(ae_list
); i
++) {
2111 if (write_desc(proto
, fd
, 0, 0, 0, ae_list
[i
]))
2116 printk("BUG: Specified unknown proto %d", proto
);
2124 * Some structures in xfrm uapi header differ in size between
2125 * 64-bit and 32-bit ABI:
2127 * 32-bit UABI | 64-bit UABI
2128 * -------------------------------------|-------------------------------------
2129 * sizeof(xfrm_usersa_info) = 220 | sizeof(xfrm_usersa_info) = 224
2130 * sizeof(xfrm_userpolicy_info) = 164 | sizeof(xfrm_userpolicy_info) = 168
2131 * sizeof(xfrm_userspi_info) = 228 | sizeof(xfrm_userspi_info) = 232
2132 * sizeof(xfrm_user_acquire) = 276 | sizeof(xfrm_user_acquire) = 280
2133 * sizeof(xfrm_user_expire) = 224 | sizeof(xfrm_user_expire) = 232
2134 * sizeof(xfrm_user_polexpire) = 168 | sizeof(xfrm_user_polexpire) = 176
2136 * Check the affected by the UABI difference structures.
2137 * Also, check translation for xfrm_set_spdinfo: it has it's own attributes
2138 * which needs to be correctly copied, but not translated.
2140 const unsigned int compat_plan
= 5;
2141 static int write_compat_struct_tests(int test_desc_fd
)
2143 struct xfrm_desc desc
= {};
2145 desc
.type
= ALLOCATE_SPI
;
2146 desc
.proto
= IPPROTO_AH
;
2147 strncpy(desc
.a_algo
, ah_list
[0], ALGO_LEN
- 1);
2149 if (__write_desc(test_desc_fd
, &desc
))
2152 desc
.type
= MONITOR_ACQUIRE
;
2153 if (__write_desc(test_desc_fd
, &desc
))
2156 desc
.type
= EXPIRE_STATE
;
2157 if (__write_desc(test_desc_fd
, &desc
))
2160 desc
.type
= EXPIRE_POLICY
;
2161 if (__write_desc(test_desc_fd
, &desc
))
2164 desc
.type
= SPDINFO_ATTRS
;
2165 if (__write_desc(test_desc_fd
, &desc
))
2171 static int write_test_plan(int test_desc_fd
)
2182 if (close(test_desc_fd
))
2183 printk("close(): %m");
2187 if (write_compat_struct_tests(test_desc_fd
))
2190 for (i
= 0; i
< ARRAY_SIZE(proto_list
); i
++) {
2191 if (write_proto_plan(test_desc_fd
, proto_list
[i
]))
2198 static int children_cleanup(void)
2200 unsigned ret
= KSFT_PASS
;
2204 pid_t p
= wait(&status
);
2206 if ((p
< 0) && errno
== ECHILD
)
2214 if (!WIFEXITED(status
)) {
2219 if (WEXITSTATUS(status
) == KSFT_FAIL
)
2226 typedef void (*print_res
)(const char *, ...);
2228 static int check_results(void)
2230 struct test_result tr
= {};
2231 struct xfrm_desc
*d
= &tr
.desc
;
2232 int ret
= KSFT_PASS
;
2235 ssize_t received
= read(results_fd
[0], &tr
, sizeof(tr
));
2238 if (received
== 0) /* EOF */
2241 if (received
!= sizeof(tr
)) {
2242 pr_err("read() returned %zd", received
);
2248 result
= ksft_test_result_pass
;
2252 result
= ksft_test_result_fail
;
2256 result(" %s: [%u, '%s', '%s', '%s', '%s', %u]\n",
2257 desc_name
[d
->type
], (unsigned int)d
->proto
, d
->a_algo
,
2258 d
->e_algo
, d
->c_algo
, d
->ae_algo
, d
->icv_len
);
2264 int main(int argc
, char **argv
)
2266 long nr_process
= 1;
2267 int route_sock
= -1, ret
= KSFT_SKIP
;
2268 int test_desc_fd
[2];
2279 nr_process
= strtol(argv
[1], &endptr
, 10);
2280 if ((errno
== ERANGE
&& (nr_process
== LONG_MAX
|| nr_process
== LONG_MIN
))
2281 || (errno
!= 0 && nr_process
== 0)
2282 || (endptr
== argv
[1]) || (*endptr
!= '\0')) {
2283 printk("Failed to parse [nr_process]");
2287 if (nr_process
> MAX_PROCESSES
|| nr_process
< 1) {
2288 printk("nr_process should be between [1; %u]",
2295 page_size
= sysconf(_SC_PAGESIZE
);
2297 ksft_exit_skip("sysconf(): %m\n");
2299 if (pipe2(test_desc_fd
, O_DIRECT
) < 0)
2300 ksft_exit_skip("pipe(): %m\n");
2302 if (pipe2(results_fd
, O_DIRECT
) < 0)
2303 ksft_exit_skip("pipe(): %m\n");
2305 if (init_namespaces())
2306 ksft_exit_skip("Failed to create namespaces\n");
2308 if (netlink_sock(&route_sock
, &route_seq
, NETLINK_ROUTE
))
2309 ksft_exit_skip("Failed to open netlink route socket\n");
2311 for (i
= 0; i
< nr_process
; i
++) {
2312 char veth
[VETH_LEN
];
2314 snprintf(veth
, VETH_LEN
, VETH_FMT
, i
);
2316 if (veth_add(route_sock
, route_seq
++, veth
, nsfd_childa
, veth
, nsfd_childb
)) {
2318 ksft_exit_fail_msg("Failed to create veth device");
2321 if (start_child(i
, veth
, test_desc_fd
)) {
2323 ksft_exit_fail_msg("Child %u failed to start", i
);
2327 if (close(route_sock
) || close(test_desc_fd
[0]) || close(results_fd
[1]))
2328 ksft_exit_fail_msg("close(): %m");
2330 ksft_set_plan(proto_plan
+ compat_plan
);
2332 if (write_test_plan(test_desc_fd
[1]))
2333 ksft_exit_fail_msg("Failed to write test plan to pipe");
2335 ret
= check_results();
2337 if (children_cleanup() == KSFT_FAIL
)