xref: /linux/tools/testing/selftests/net/tun.c (revision 42a9fb3382fc2573e92f41d203b095d9a372cfc9)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #define _GNU_SOURCE
4 
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <sched.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <linux/if_tun.h>
13 #include <sys/ioctl.h>
14 #include <sys/socket.h>
15 
16 #include "kselftest_harness.h"
17 #include "tuntap_helpers.h"
18 
19 static const char param_dev_geneve_name[] = "geneve1";
20 static unsigned char param_hwaddr_outer_dst[] = { 0x00, 0xfe, 0x98,
21 						  0x14, 0x22, 0x42 };
22 static unsigned char param_hwaddr_outer_src[] = { 0x00, 0xfe, 0x98,
23 						  0x94, 0xd2, 0x43 };
24 static unsigned char param_hwaddr_inner_dst[] = { 0x00, 0xfe, 0x98,
25 						  0x94, 0x22, 0xcc };
26 static unsigned char param_hwaddr_inner_src[] = { 0x00, 0xfe, 0x98,
27 						  0x94, 0xd2, 0xdd };
28 
29 static struct in_addr param_ipaddr4_outer_dst = {
30 	__constant_htonl(0xac100001),
31 };
32 
33 static struct in_addr param_ipaddr4_outer_src = {
34 	__constant_htonl(0xac100002),
35 };
36 
37 static struct in_addr param_ipaddr4_inner_dst = {
38 	__constant_htonl(0xac100101),
39 };
40 
41 static struct in_addr param_ipaddr4_inner_src = {
42 	__constant_htonl(0xac100102),
43 };
44 
45 static struct in6_addr param_ipaddr6_outer_dst = {
46 	{ { 0xfd, 0x00, 0x0d, 0xb8, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
47 };
48 
49 static struct in6_addr param_ipaddr6_outer_src = {
50 	{ { 0xfd, 0x00, 0x0d, 0xb8, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 } },
51 };
52 
53 static struct in6_addr param_ipaddr6_inner_dst = {
54 	{ { 0xfd, 0x00, 0x0d, 0xb8, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
55 };
56 
57 static struct in6_addr param_ipaddr6_inner_src = {
58 	{ { 0xfd, 0x00, 0x0d, 0xb8, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 } },
59 };
60 
61 #ifndef BIT
62 #define BIT(nr) (1UL << (nr))
63 #endif
64 
65 #define VN_ID 1
66 #define VN_PORT 4789
67 #define UDP_SRC_PORT 22
68 #define UDP_DST_PORT 48878
69 #define IPPREFIX_LEN 24
70 #define IP6PREFIX_LEN 64
71 #define TIMEOUT_SEC 10
72 #define TIMEOUT_USEC 100000
73 #define MAX_RETRIES 20
74 
75 #define UDP_TUNNEL_GENEVE_4IN4 0x01
76 #define UDP_TUNNEL_GENEVE_6IN4 0x02
77 #define UDP_TUNNEL_GENEVE_4IN6 0x04
78 #define UDP_TUNNEL_GENEVE_6IN6 0x08
79 
80 #define UDP_TUNNEL_MAX_SEGMENTS BIT(7)
81 
82 #define UDP_TUNNEL_OUTER_IPV4 (UDP_TUNNEL_GENEVE_4IN4 | UDP_TUNNEL_GENEVE_6IN4)
83 #define UDP_TUNNEL_INNER_IPV4 (UDP_TUNNEL_GENEVE_4IN4 | UDP_TUNNEL_GENEVE_4IN6)
84 
85 #define UDP_TUNNEL_GENEVE_4IN4_HDRLEN                        \
86 	(ETH_HLEN + 2 * sizeof(struct iphdr) + GENEVE_HLEN + \
87 	 2 * sizeof(struct udphdr))
88 #define UDP_TUNNEL_GENEVE_6IN6_HDRLEN                          \
89 	(ETH_HLEN + 2 * sizeof(struct ipv6hdr) + GENEVE_HLEN + \
90 	 2 * sizeof(struct udphdr))
91 #define UDP_TUNNEL_GENEVE_4IN6_HDRLEN                               \
92 	(ETH_HLEN + sizeof(struct iphdr) + sizeof(struct ipv6hdr) + \
93 	 GENEVE_HLEN + 2 * sizeof(struct udphdr))
94 #define UDP_TUNNEL_GENEVE_6IN4_HDRLEN                               \
95 	(ETH_HLEN + sizeof(struct ipv6hdr) + sizeof(struct iphdr) + \
96 	 GENEVE_HLEN + 2 * sizeof(struct udphdr))
97 
98 #define UDP_TUNNEL_HDRLEN(type)                                             \
99 	((type) == UDP_TUNNEL_GENEVE_4IN4 ? UDP_TUNNEL_GENEVE_4IN4_HDRLEN : \
100 	 (type) == UDP_TUNNEL_GENEVE_6IN6 ? UDP_TUNNEL_GENEVE_6IN6_HDRLEN : \
101 	 (type) == UDP_TUNNEL_GENEVE_4IN6 ? UDP_TUNNEL_GENEVE_4IN6_HDRLEN : \
102 	 (type) == UDP_TUNNEL_GENEVE_6IN4 ? UDP_TUNNEL_GENEVE_6IN4_HDRLEN : \
103 					    0)
104 
105 #define UDP_TUNNEL_MSS(type) (ETH_DATA_LEN - UDP_TUNNEL_HDRLEN(type))
106 #define UDP_TUNNEL_MAX(type, is_tap) \
107 	(ETH_MAX_MTU - UDP_TUNNEL_HDRLEN(type) - ((is_tap) ? ETH_HLEN : 0))
108 
109 #define TUN_VNET_TNL_SIZE sizeof(struct virtio_net_hdr_v1_hash_tunnel)
110 #define MAX_VNET_TUNNEL_PACKET_SZ                                       \
111 	(TUN_VNET_TNL_SIZE + ETH_HLEN + UDP_TUNNEL_GENEVE_6IN6_HDRLEN + \
112 	 ETH_MAX_MTU)
113 
114 struct geneve_setup_config {
115 	int family;
116 	union {
117 		struct in_addr r4;
118 		struct in6_addr r6;
119 	} remote;
120 	__be32 vnid;
121 	__be16 vnport;
122 	unsigned char hwaddr[6];
123 	uint8_t csum;
124 };
125 
126 static int tun_attach(int fd, char *dev)
127 {
128 	struct ifreq ifr;
129 
130 	memset(&ifr, 0, sizeof(ifr));
131 	strcpy(ifr.ifr_name, dev);
132 	ifr.ifr_flags = IFF_ATTACH_QUEUE;
133 
134 	return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
135 }
136 
137 static int tun_detach(int fd, char *dev)
138 {
139 	struct ifreq ifr;
140 
141 	memset(&ifr, 0, sizeof(ifr));
142 	strcpy(ifr.ifr_name, dev);
143 	ifr.ifr_flags = IFF_DETACH_QUEUE;
144 
145 	return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
146 }
147 
148 static int tun_alloc(char *dev)
149 {
150 	struct ifreq ifr;
151 	int fd, err;
152 
153 	fd = open("/dev/net/tun", O_RDWR);
154 	if (fd < 0) {
155 		fprintf(stderr, "can't open tun: %s\n", strerror(errno));
156 		return fd;
157 	}
158 
159 	memset(&ifr, 0, sizeof(ifr));
160 	strcpy(ifr.ifr_name, dev);
161 	ifr.ifr_flags = IFF_TAP | IFF_NAPI | IFF_MULTI_QUEUE;
162 
163 	err = ioctl(fd, TUNSETIFF, (void *)&ifr);
164 	if (err < 0) {
165 		fprintf(stderr, "can't TUNSETIFF: %s\n", strerror(errno));
166 		close(fd);
167 		return err;
168 	}
169 	strcpy(dev, ifr.ifr_name);
170 	return fd;
171 }
172 
173 static int tun_delete(char *dev)
174 {
175 	return ip_link_del(dev);
176 }
177 
178 static int tun_open(char *dev, const int flags, const int hdrlen,
179 		    const int features, const unsigned char *mac_addr)
180 {
181 	struct ifreq ifr = { 0 };
182 	int fd, sk = -1;
183 
184 	fd = open("/dev/net/tun", O_RDWR);
185 	if (fd < 0) {
186 		perror("open");
187 		return -1;
188 	}
189 
190 	ifr.ifr_flags = flags;
191 	if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) {
192 		perror("ioctl(TUNSETIFF)");
193 		goto err;
194 	}
195 	strcpy(dev, ifr.ifr_name);
196 
197 	if (hdrlen > 0) {
198 		if (ioctl(fd, TUNSETVNETHDRSZ, &hdrlen) < 0) {
199 			perror("ioctl(TUNSETVNETHDRSZ)");
200 			goto err;
201 		}
202 	}
203 
204 	if (features) {
205 		if (ioctl(fd, TUNSETOFFLOAD, features) < 0) {
206 			perror("ioctl(TUNSETOFFLOAD)");
207 			goto err;
208 		}
209 	}
210 
211 	sk = socket(PF_INET, SOCK_DGRAM, 0);
212 	if (sk < 0) {
213 		perror("socket");
214 		goto err;
215 	}
216 
217 	if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
218 		perror("ioctl(SIOCGIFFLAGS)");
219 		goto err;
220 	}
221 
222 	ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
223 	if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
224 		perror("ioctl(SIOCSIFFLAGS)");
225 		goto err;
226 	}
227 
228 	if (mac_addr && flags & IFF_TAP) {
229 		ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
230 		memcpy(ifr.ifr_hwaddr.sa_data, mac_addr, ETH_ALEN);
231 
232 		if (ioctl(sk, SIOCSIFHWADDR, &ifr) < 0) {
233 			perror("ioctl(SIOCSIFHWADDR)");
234 			goto err;
235 		}
236 	}
237 
238 out:
239 	if (sk >= 0)
240 		close(sk);
241 	return fd;
242 
243 err:
244 	close(fd);
245 	fd = -1;
246 	goto out;
247 }
248 
249 static size_t sockaddr_len(int family)
250 {
251 	return (family == AF_INET) ? sizeof(struct sockaddr_in) :
252 				     sizeof(struct sockaddr_in6);
253 }
254 
255 static int geneve_fill_newlink(struct rt_link_newlink_req *req, void *data)
256 {
257 	struct geneve_setup_config *cfg = data;
258 
259 #define SET_GENEVE_REMOTE rt_link_newlink_req_set_linkinfo_data_geneve_remote
260 #define SET_GENEVE_REMOTE6 rt_link_newlink_req_set_linkinfo_data_geneve_remote6
261 
262 	rt_link_newlink_req_set_address(req, cfg->hwaddr, ETH_ALEN);
263 	rt_link_newlink_req_set_linkinfo_data_geneve_id(req, cfg->vnid);
264 	rt_link_newlink_req_set_linkinfo_data_geneve_port(req, cfg->vnport);
265 	rt_link_newlink_req_set_linkinfo_data_geneve_udp_csum(req, cfg->csum);
266 
267 	if (cfg->family == AF_INET)
268 		SET_GENEVE_REMOTE(req, cfg->remote.r4.s_addr);
269 	else
270 		SET_GENEVE_REMOTE6(req, &cfg->remote.r6,
271 				   sizeof(cfg->remote.r6));
272 
273 	return 0;
274 }
275 
276 static int geneve_create(const char *dev, int family, void *remote,
277 			 void *hwaddr)
278 {
279 	struct geneve_setup_config geneve;
280 
281 	memset(&geneve, 0, sizeof(geneve));
282 	geneve.vnid = VN_ID;
283 	geneve.vnport = htons(VN_PORT);
284 	geneve.csum = 1;
285 	geneve.family = family;
286 	if (family == AF_INET)
287 		memcpy(&geneve.remote.r4, remote, sizeof(struct in_addr));
288 	else
289 		memcpy(&geneve.remote.r6, remote, sizeof(struct in6_addr));
290 	memcpy(geneve.hwaddr, hwaddr, ETH_ALEN);
291 
292 	return ip_link_add(dev, "geneve", geneve_fill_newlink, (void *)&geneve);
293 }
294 
295 static int set_pmtu_discover(int fd, bool is_ipv4)
296 {
297 	int level, name, val;
298 
299 	if (is_ipv4) {
300 		level = SOL_IP;
301 		name = IP_MTU_DISCOVER;
302 		val = IP_PMTUDISC_DO;
303 	} else {
304 		level = SOL_IPV6;
305 		name = IPV6_MTU_DISCOVER;
306 		val = IPV6_PMTUDISC_DO;
307 	}
308 
309 	return setsockopt(fd, level, name, &val, sizeof(val));
310 }
311 
312 static int udp_socket_open(struct sockaddr_storage *ssa, bool do_frag,
313 			   bool do_connect, struct sockaddr_storage *dsa)
314 {
315 	struct timeval to = { .tv_sec = TIMEOUT_SEC };
316 	int fd, family = ssa->ss_family;
317 	int salen = sockaddr_len(family);
318 
319 	fd = socket(family, SOCK_DGRAM, 0);
320 	if (fd < 0)
321 		return -1;
322 
323 	if (bind(fd, (struct sockaddr *)ssa, salen) < 0) {
324 		perror("bind");
325 		goto err;
326 	}
327 
328 	if (do_connect && connect(fd, (struct sockaddr *)dsa, salen) < 0) {
329 		perror("connect");
330 		goto err;
331 	}
332 
333 	if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to)) < 0) {
334 		perror("setsockopt(SO_RCVTIMEO)");
335 		goto err;
336 	}
337 
338 	if (!do_frag && set_pmtu_discover(fd, family == AF_INET) < 0) {
339 		perror("set_pmtu_discover");
340 		goto err;
341 	}
342 	return fd;
343 
344 err:
345 	close(fd);
346 	return -1;
347 }
348 
349 static void parse_route_rsp(struct rt_route_getroute_rsp *rsp, void *rtm_type)
350 {
351 	*(uint8_t *)rtm_type = rsp->_hdr.rtm_type;
352 }
353 
354 static int ip_route_check(const char *intf, int family, void *addr)
355 {
356 	uint8_t rtm_type, table = RT_TABLE_LOCAL;
357 	int retries = MAX_RETRIES;
358 
359 	while (retries-- > 0) {
360 		if (ip_route_get(intf, family, table, addr, parse_route_rsp,
361 				 &rtm_type) == 0 &&
362 		    rtm_type == RTN_LOCAL)
363 			break;
364 
365 		usleep(TIMEOUT_USEC);
366 	}
367 
368 	if (retries < 0)
369 		return -1;
370 
371 	return 0;
372 }
373 
374 static int send_gso_udp_msg(int socket, struct sockaddr_storage *addr,
375 			    uint8_t *send_buf, int send_len, int gso_size)
376 {
377 	char control[CMSG_SPACE(sizeof(uint16_t))] = { 0 };
378 	int alen = sockaddr_len(addr->ss_family);
379 	struct msghdr msg = { 0 };
380 	struct iovec iov = { 0 };
381 	int ret;
382 
383 	iov.iov_base = send_buf;
384 	iov.iov_len = send_len;
385 
386 	msg.msg_iov = &iov;
387 	msg.msg_iovlen = 1;
388 	msg.msg_name = addr;
389 	msg.msg_namelen = alen;
390 
391 	if (gso_size > 0) {
392 		struct cmsghdr *cmsg;
393 
394 		msg.msg_control = control;
395 		msg.msg_controllen = sizeof(control);
396 
397 		cmsg = CMSG_FIRSTHDR(&msg);
398 		cmsg->cmsg_level = SOL_UDP;
399 		cmsg->cmsg_type = UDP_SEGMENT;
400 		cmsg->cmsg_len = CMSG_LEN(sizeof(uint16_t));
401 		*(uint16_t *)CMSG_DATA(cmsg) = gso_size;
402 	}
403 
404 	ret = sendmsg(socket, &msg, 0);
405 	if (ret < 0)
406 		perror("sendmsg");
407 
408 	return ret;
409 }
410 
411 static int validate_hdrlen(uint8_t **cur, int *len, int x)
412 {
413 	if (*len < x)
414 		return -1;
415 	*cur += x;
416 	*len -= x;
417 	return 0;
418 }
419 
420 static int parse_udp_tunnel_vnet_packet(uint8_t *buf, int len, int tunnel_type,
421 					bool is_tap)
422 {
423 	struct ipv6hdr *iph6;
424 	struct udphdr *udph;
425 	struct iphdr *iph4;
426 	uint8_t *cur = buf;
427 
428 	if (validate_hdrlen(&cur, &len, TUN_VNET_TNL_SIZE))
429 		return -1;
430 
431 	if (is_tap) {
432 		if (validate_hdrlen(&cur, &len, ETH_HLEN))
433 			return -1;
434 	}
435 
436 	if (tunnel_type & UDP_TUNNEL_OUTER_IPV4) {
437 		iph4 = (struct iphdr *)cur;
438 		if (validate_hdrlen(&cur, &len, sizeof(struct iphdr)))
439 			return -1;
440 		if (iph4->version != 4 || iph4->protocol != IPPROTO_UDP)
441 			return -1;
442 	} else {
443 		iph6 = (struct ipv6hdr *)cur;
444 		if (validate_hdrlen(&cur, &len, sizeof(struct ipv6hdr)))
445 			return -1;
446 		if (iph6->version != 6 || iph6->nexthdr != IPPROTO_UDP)
447 			return -1;
448 	}
449 
450 	udph = (struct udphdr *)cur;
451 	if (validate_hdrlen(&cur, &len, sizeof(struct udphdr)))
452 		return -1;
453 	if (ntohs(udph->dest) != VN_PORT)
454 		return -1;
455 
456 	if (validate_hdrlen(&cur, &len, GENEVE_HLEN))
457 		return -1;
458 	if (validate_hdrlen(&cur, &len, ETH_HLEN))
459 		return -1;
460 
461 	if (tunnel_type & UDP_TUNNEL_INNER_IPV4) {
462 		iph4 = (struct iphdr *)cur;
463 		if (validate_hdrlen(&cur, &len, sizeof(struct iphdr)))
464 			return -1;
465 		if (iph4->version != 4 || iph4->protocol != IPPROTO_UDP)
466 			return -1;
467 	} else {
468 		iph6 = (struct ipv6hdr *)cur;
469 		if (validate_hdrlen(&cur, &len, sizeof(struct ipv6hdr)))
470 			return -1;
471 		if (iph6->version != 6 || iph6->nexthdr != IPPROTO_UDP)
472 			return -1;
473 	}
474 
475 	udph = (struct udphdr *)cur;
476 	if (validate_hdrlen(&cur, &len, sizeof(struct udphdr)))
477 		return -1;
478 	if (ntohs(udph->dest) != UDP_DST_PORT)
479 		return -1;
480 
481 	return len;
482 }
483 
484 FIXTURE(tun)
485 {
486 	char ifname[IFNAMSIZ];
487 	int fd, fd2;
488 };
489 
490 FIXTURE_SETUP(tun)
491 {
492 	if (unshare(CLONE_NEWNET))
493 		SKIP(return, "Cannot create network namespace: %s",
494 		     strerror(errno));
495 
496 	memset(self->ifname, 0, sizeof(self->ifname));
497 
498 	self->fd = tun_alloc(self->ifname);
499 	ASSERT_GE(self->fd, 0);
500 
501 	self->fd2 = tun_alloc(self->ifname);
502 	ASSERT_GE(self->fd2, 0);
503 }
504 
505 FIXTURE_TEARDOWN(tun)
506 {
507 	if (self->fd >= 0)
508 		close(self->fd);
509 	if (self->fd2 >= 0)
510 		close(self->fd2);
511 }
512 
513 TEST_F(tun, delete_detach_close)
514 {
515 	EXPECT_EQ(tun_delete(self->ifname), 0);
516 	EXPECT_EQ(tun_detach(self->fd, self->ifname), -1);
517 	EXPECT_EQ(errno, 22);
518 }
519 
520 TEST_F(tun, detach_delete_close)
521 {
522 	EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
523 	EXPECT_EQ(tun_delete(self->ifname), 0);
524 }
525 
526 TEST_F(tun, detach_close_delete)
527 {
528 	EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
529 	close(self->fd);
530 	self->fd = -1;
531 	EXPECT_EQ(tun_delete(self->ifname), 0);
532 }
533 
534 TEST_F(tun, reattach_delete_close)
535 {
536 	EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
537 	EXPECT_EQ(tun_attach(self->fd, self->ifname), 0);
538 	EXPECT_EQ(tun_delete(self->ifname), 0);
539 }
540 
541 TEST_F(tun, reattach_close_delete)
542 {
543 	EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
544 	EXPECT_EQ(tun_attach(self->fd, self->ifname), 0);
545 	close(self->fd);
546 	self->fd = -1;
547 	EXPECT_EQ(tun_delete(self->ifname), 0);
548 }
549 
550 FIXTURE(tun_vnet_udptnl)
551 {
552 	char ifname[IFNAMSIZ];
553 	int fd, sock;
554 };
555 
556 FIXTURE_VARIANT(tun_vnet_udptnl)
557 {
558 	int tunnel_type;
559 	int gso_size;
560 	int data_size;
561 	int r_num_mss;
562 	bool is_tap, no_gso;
563 };
564 
565 /* clang-format off */
566 #define TUN_VNET_UDPTNL_VARIANT_ADD(type, desc)                              \
567 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_nogsosz_1byte) {         \
568 		/* no GSO: send a single byte */                             \
569 		.tunnel_type = type,                                         \
570 		.data_size = 1,                                              \
571 		.r_num_mss = 1,                                              \
572 		.is_tap = true,                                              \
573 		.no_gso = true,                                              \
574 	};                                                                   \
575 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_nogsosz_1mss) {          \
576 		/* no GSO: send a single MSS, fall back to no GSO */         \
577 		.tunnel_type = type,                                         \
578 		.data_size = UDP_TUNNEL_MSS(type),                           \
579 		.r_num_mss = 1,                                              \
580 		.is_tap = true,                                              \
581 		.no_gso = true,                                              \
582 	};                                                                   \
583 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_nogsosz_gtmss) {         \
584 		/* no GSO: send a single MSS + 1B: fail */                   \
585 		.tunnel_type = type,                                         \
586 		.data_size = UDP_TUNNEL_MSS(type) + 1,                       \
587 		.r_num_mss = 1,                                              \
588 		.is_tap = true,                                              \
589 		.no_gso = true,                                              \
590 	};                                                                   \
591 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_1byte) {                 \
592 		/* GSO: send 1 byte, gso 1 byte, fall back to no GSO */      \
593 		.tunnel_type = type,                                         \
594 		.gso_size = 1,                                               \
595 		.data_size = 1,                                              \
596 		.r_num_mss = 1,                                              \
597 		.is_tap = true,                                              \
598 		.no_gso = true,                                              \
599 	};                                                                   \
600 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_1mss) {                  \
601 		/* send a single MSS: fall back to no GSO */                 \
602 		.tunnel_type = type,                                         \
603 		.gso_size = UDP_TUNNEL_MSS(type),                            \
604 		.data_size = UDP_TUNNEL_MSS(type),                           \
605 		.r_num_mss = 1,                                              \
606 		.is_tap = true,                                              \
607 		.no_gso = true,                                              \
608 	};                                                                   \
609 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_ltgso) {                 \
610 		/* data <= MSS < gso: will fall back to no GSO */            \
611 		.tunnel_type = type,                                         \
612 		.gso_size = UDP_TUNNEL_MSS(type) + 1,                        \
613 		.data_size = UDP_TUNNEL_MSS(type),                           \
614 		.r_num_mss = 1,                                              \
615 		.is_tap = true,                                              \
616 		.no_gso = true,                                              \
617 	};                                                                   \
618 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_gtgso) {                 \
619 		/* GSO: a single MSS + 1B */                                 \
620 		.tunnel_type = type,                                         \
621 		.gso_size = UDP_TUNNEL_MSS(type),                            \
622 		.data_size = UDP_TUNNEL_MSS(type) + 1,                       \
623 		.r_num_mss = 2,                                              \
624 		.is_tap = true,                                              \
625 	};                                                                   \
626 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_2mss) {                  \
627 		/* no GSO: send exactly 2 MSS */                             \
628 		.tunnel_type = type,                                         \
629 		.gso_size = UDP_TUNNEL_MSS(type),                            \
630 		.data_size = UDP_TUNNEL_MSS(type) * 2,                       \
631 		.r_num_mss = 2,                                              \
632 		.is_tap = true,                                              \
633 	};                                                                   \
634 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_maxbytes) {              \
635 		/* GSO: send max bytes */                                    \
636 		.tunnel_type = type,                                         \
637 		.gso_size = UDP_TUNNEL_MSS(type),                            \
638 		.data_size = UDP_TUNNEL_MAX(type, true),                     \
639 		.r_num_mss = UDP_TUNNEL_MAX(type, true) /                    \
640 			     UDP_TUNNEL_MSS(type) + 1,                       \
641 		.is_tap = true,                                              \
642 	};                                                                   \
643 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_over_maxbytes) {         \
644 		/* GSO: send oversize max bytes: fail */                     \
645 		.tunnel_type = type,                                         \
646 		.gso_size = UDP_TUNNEL_MSS(type),                            \
647 		.data_size = ETH_MAX_MTU,                                    \
648 		.r_num_mss = ETH_MAX_MTU / UDP_TUNNEL_MSS(type) + 1,         \
649 		.is_tap = true,                                              \
650 	};                                                                   \
651 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_maxsegs) {               \
652 		/* GSO: send max number of min sized segments */             \
653 		.tunnel_type = type,                                         \
654 		.gso_size = 1,                                               \
655 		.data_size = UDP_TUNNEL_MAX_SEGMENTS,                        \
656 		.r_num_mss = UDP_TUNNEL_MAX_SEGMENTS,                        \
657 		.is_tap = true,                                              \
658 	};                                                                   \
659 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_5byte) {                 \
660 		/* GSO: send 5 bytes, gso 2 bytes */                         \
661 		.tunnel_type = type,                                         \
662 		.gso_size = 2,                                               \
663 		.data_size = 5,                                              \
664 		.r_num_mss = 3,                                              \
665 		.is_tap = true,                                              \
666 	} /* clang-format on */
667 
668 TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_4IN4, 4in4);
669 TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_6IN4, 6in4);
670 TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_4IN6, 4in6);
671 TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_6IN6, 6in6);
672 
673 static void assign_ifaddr_vars(int family, int is_outer, void **srcip,
674 			       void **dstip, void **srcmac, void **dstmac)
675 {
676 	if (is_outer) {
677 		if (family == AF_INET) {
678 			*srcip = (void *)&param_ipaddr4_outer_src;
679 			*dstip = (void *)&param_ipaddr4_outer_dst;
680 		} else {
681 			*srcip = (void *)&param_ipaddr6_outer_src;
682 			*dstip = (void *)&param_ipaddr6_outer_dst;
683 		}
684 		*srcmac = param_hwaddr_outer_src;
685 		*dstmac = param_hwaddr_outer_dst;
686 	} else {
687 		if (family == AF_INET) {
688 			*srcip = (void *)&param_ipaddr4_inner_src;
689 			*dstip = (void *)&param_ipaddr4_inner_dst;
690 		} else {
691 			*srcip = (void *)&param_ipaddr6_inner_src;
692 			*dstip = (void *)&param_ipaddr6_inner_dst;
693 		}
694 		*srcmac = param_hwaddr_inner_src;
695 		*dstmac = param_hwaddr_inner_dst;
696 	}
697 }
698 
699 static void assign_sockaddr_vars(int family, int is_outer,
700 				 struct sockaddr_storage *src,
701 				 struct sockaddr_storage *dst)
702 {
703 	src->ss_family = family;
704 	dst->ss_family = family;
705 
706 	if (family == AF_INET) {
707 		struct sockaddr_in *s4 = (struct sockaddr_in *)src;
708 		struct sockaddr_in *d4 = (struct sockaddr_in *)dst;
709 
710 		s4->sin_addr = is_outer ? param_ipaddr4_outer_src :
711 					  param_ipaddr4_inner_src;
712 		d4->sin_addr = is_outer ? param_ipaddr4_outer_dst :
713 					  param_ipaddr4_inner_dst;
714 		if (!is_outer) {
715 			s4->sin_port = htons(UDP_SRC_PORT);
716 			d4->sin_port = htons(UDP_DST_PORT);
717 		}
718 	} else {
719 		struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)src;
720 		struct sockaddr_in6 *d6 = (struct sockaddr_in6 *)dst;
721 
722 		s6->sin6_addr = is_outer ? param_ipaddr6_outer_src :
723 					   param_ipaddr6_inner_src;
724 		d6->sin6_addr = is_outer ? param_ipaddr6_outer_dst :
725 					   param_ipaddr6_inner_dst;
726 		if (!is_outer) {
727 			s6->sin6_port = htons(UDP_SRC_PORT);
728 			d6->sin6_port = htons(UDP_DST_PORT);
729 		}
730 	}
731 }
732 
733 FIXTURE_SETUP(tun_vnet_udptnl)
734 {
735 	int ret, family, prefix, flags, features;
736 	int tunnel_type = variant->tunnel_type;
737 	struct sockaddr_storage ssa, dsa;
738 	void *sip, *dip, *smac, *dmac;
739 
740 	if (unshare(CLONE_NEWNET))
741 		SKIP(return, "Cannot create network namespace: %s",
742 		     strerror(errno));
743 
744 	flags = (variant->is_tap ? IFF_TAP : IFF_TUN) | IFF_VNET_HDR |
745 		IFF_MULTI_QUEUE | IFF_NO_PI;
746 	features = TUN_F_CSUM | TUN_F_UDP_TUNNEL_GSO |
747 		   TUN_F_UDP_TUNNEL_GSO_CSUM | TUN_F_USO4 | TUN_F_USO6;
748 	self->fd = tun_open(self->ifname, flags, TUN_VNET_TNL_SIZE, features,
749 			    param_hwaddr_outer_src);
750 	ASSERT_GE(self->fd, 0);
751 
752 	family = (tunnel_type & UDP_TUNNEL_OUTER_IPV4) ? AF_INET : AF_INET6;
753 	prefix = (family == AF_INET) ? IPPREFIX_LEN : IP6PREFIX_LEN;
754 	assign_ifaddr_vars(family, 1, &sip, &dip, &smac, &dmac);
755 
756 	ret = ip_addr_add(self->ifname, family, sip, prefix);
757 	ASSERT_EQ(ret, 0);
758 	ret = ip_neigh_add(self->ifname, family, dip, dmac);
759 	ASSERT_EQ(ret, 0);
760 	ret = ip_route_check(self->ifname, family, sip);
761 	ASSERT_EQ(ret, 0);
762 
763 	ret = geneve_create(param_dev_geneve_name, family, dip,
764 			    param_hwaddr_inner_src);
765 	ASSERT_EQ(ret, 0);
766 
767 	family = (tunnel_type & UDP_TUNNEL_INNER_IPV4) ? AF_INET : AF_INET6;
768 	prefix = (family == AF_INET) ? IPPREFIX_LEN : IP6PREFIX_LEN;
769 	assign_ifaddr_vars(family, 0, &sip, &dip, &smac, &dmac);
770 
771 	ret = ip_addr_add(param_dev_geneve_name, family, sip, prefix);
772 	ASSERT_EQ(ret, 0);
773 	ret = ip_neigh_add(param_dev_geneve_name, family, dip, dmac);
774 	ASSERT_EQ(ret, 0);
775 	ret = ip_route_check(param_dev_geneve_name, family, sip);
776 	ASSERT_EQ(ret, 0);
777 
778 	assign_sockaddr_vars(family, 0, &ssa, &dsa);
779 	self->sock = udp_socket_open(&ssa, false, true, &dsa);
780 	ASSERT_GE(self->sock, 0);
781 }
782 
783 FIXTURE_TEARDOWN(tun_vnet_udptnl)
784 {
785 	int ret;
786 
787 	if (self->sock != -1)
788 		close(self->sock);
789 
790 	ret = ip_link_del(param_dev_geneve_name);
791 	EXPECT_EQ(ret, 0);
792 
793 	ret = tun_delete(self->ifname);
794 	EXPECT_EQ(ret, 0);
795 }
796 
797 static int build_gso_packet_into_tun(const FIXTURE_VARIANT(tun_vnet_udptnl) *
798 					     variant,
799 				     uint8_t *buf)
800 {
801 	int pktlen, hlen, proto, inner_family, outer_family;
802 	int tunnel_type = variant->tunnel_type;
803 	int payload_len = variant->data_size;
804 	int gso_size = variant->gso_size;
805 	uint8_t *outer_udph, *cur = buf;
806 	void *sip, *dip, *smac, *dmac;
807 	bool is_tap = variant->is_tap;
808 
809 	hlen = (is_tap ? ETH_HLEN : 0) + UDP_TUNNEL_HDRLEN(tunnel_type);
810 	inner_family = (tunnel_type & UDP_TUNNEL_INNER_IPV4) ? AF_INET :
811 							       AF_INET6;
812 	outer_family = (tunnel_type & UDP_TUNNEL_OUTER_IPV4) ? AF_INET :
813 							       AF_INET6;
814 
815 	cur += build_virtio_net_hdr_v1_hash_tunnel(cur, is_tap, hlen, gso_size,
816 						   outer_family, inner_family);
817 
818 	pktlen = hlen + payload_len;
819 	assign_ifaddr_vars(outer_family, 1, &sip, &dip, &smac, &dmac);
820 
821 	if (is_tap) {
822 		proto = outer_family == AF_INET ? ETH_P_IP : ETH_P_IPV6;
823 		pktlen -= ETH_HLEN;
824 		cur += build_eth(cur, proto, dmac, smac);
825 	}
826 
827 	if (outer_family == AF_INET) {
828 		pktlen = pktlen - sizeof(struct iphdr);
829 		cur += build_ipv4_header(cur, IPPROTO_UDP, pktlen, dip, sip);
830 	} else {
831 		pktlen = pktlen - sizeof(struct ipv6hdr);
832 		cur += build_ipv6_header(cur, IPPROTO_UDP, 0, pktlen, dip, sip);
833 	}
834 
835 	outer_udph = cur;
836 	assign_ifaddr_vars(inner_family, 0, &sip, &dip, &smac, &dmac);
837 
838 	pktlen -= sizeof(struct udphdr);
839 	proto = inner_family == AF_INET ? ETH_P_IP : ETH_P_IPV6;
840 	cur += build_udp_header(cur, UDP_SRC_PORT, VN_PORT, pktlen);
841 	cur += build_geneve_header(cur, VN_ID);
842 	cur += build_eth(cur, proto, dmac, smac);
843 
844 	pktlen = sizeof(struct udphdr) + payload_len;
845 	if (inner_family == AF_INET)
846 		cur += build_ipv4_header(cur, IPPROTO_UDP, pktlen, dip, sip);
847 	else
848 		cur += build_ipv6_header(cur, IPPROTO_UDP, 0, pktlen, dip, sip);
849 
850 	cur += build_udp_packet(cur, UDP_DST_PORT, UDP_SRC_PORT, payload_len,
851 				inner_family, false);
852 
853 	build_udp_packet_csum(outer_udph, outer_family, false);
854 
855 	return cur - buf;
856 }
857 
858 static int
859 receive_gso_packet_from_tunnel(FIXTURE_DATA(tun_vnet_udptnl) * self,
860 			       const FIXTURE_VARIANT(tun_vnet_udptnl) * variant,
861 			       int *r_num_mss)
862 {
863 	uint8_t packet_buf[MAX_VNET_TUNNEL_PACKET_SZ];
864 	int len, total_len = 0, socket = self->sock;
865 	int payload_len = variant->data_size;
866 
867 	while (total_len < payload_len) {
868 		len = recv(socket, packet_buf, sizeof(packet_buf), 0);
869 		if (len <= 0) {
870 			if (len < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
871 				perror("recv");
872 			break;
873 		}
874 
875 		(*r_num_mss)++;
876 		total_len += len;
877 	}
878 
879 	return total_len;
880 }
881 
882 static int send_gso_packet_into_tunnel(FIXTURE_DATA(tun_vnet_udptnl) * self,
883 				       const FIXTURE_VARIANT(tun_vnet_udptnl) *
884 					       variant)
885 {
886 	int family = (variant->tunnel_type & UDP_TUNNEL_INNER_IPV4) ? AF_INET :
887 								      AF_INET6;
888 	uint8_t buf[MAX_VNET_TUNNEL_PACKET_SZ] = { 0 };
889 	int payload_len = variant->data_size;
890 	int gso_size = variant->gso_size;
891 	struct sockaddr_storage ssa, dsa;
892 
893 	assign_sockaddr_vars(family, 0, &ssa, &dsa);
894 	return send_gso_udp_msg(self->sock, &dsa, buf, payload_len, gso_size);
895 }
896 
897 static int
898 receive_gso_packet_from_tun(FIXTURE_DATA(tun_vnet_udptnl) * self,
899 			    const FIXTURE_VARIANT(tun_vnet_udptnl) * variant,
900 			    struct virtio_net_hdr_v1_hash_tunnel *vnet_hdr)
901 {
902 	struct timeval timeout = { .tv_sec = TIMEOUT_SEC };
903 	uint8_t buf[MAX_VNET_TUNNEL_PACKET_SZ];
904 	int tunnel_type = variant->tunnel_type;
905 	int payload_len = variant->data_size;
906 	bool is_tap = variant->is_tap;
907 	int ret, len, total_len = 0;
908 	int tun_fd = self->fd;
909 	fd_set fdset;
910 
911 	while (total_len < payload_len) {
912 		FD_ZERO(&fdset);
913 		FD_SET(tun_fd, &fdset);
914 
915 		ret = select(tun_fd + 1, &fdset, NULL, NULL, &timeout);
916 		if (ret <= 0) {
917 			perror("select");
918 			break;
919 		}
920 		if (!FD_ISSET(tun_fd, &fdset))
921 			continue;
922 
923 		len = read(tun_fd, buf, sizeof(buf));
924 		if (len <= 0) {
925 			if (len < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
926 				perror("read");
927 			break;
928 		}
929 
930 		len = parse_udp_tunnel_vnet_packet(buf, len, tunnel_type,
931 						   is_tap);
932 		if (len < 0)
933 			continue;
934 
935 		if (total_len == 0)
936 			memcpy(vnet_hdr, buf, TUN_VNET_TNL_SIZE);
937 
938 		total_len += len;
939 	}
940 
941 	return total_len;
942 }
943 
944 TEST_F(tun_vnet_udptnl, send_gso_packet)
945 {
946 	uint8_t pkt[MAX_VNET_TUNNEL_PACKET_SZ];
947 	int r_num_mss = 0;
948 	int ret, off;
949 
950 	memset(pkt, 0, sizeof(pkt));
951 	off = build_gso_packet_into_tun(variant, pkt);
952 	ret = write(self->fd, pkt, off);
953 	ASSERT_EQ(ret, off);
954 
955 	ret = receive_gso_packet_from_tunnel(self, variant, &r_num_mss);
956 	EXPECT_EQ(ret, variant->data_size);
957 	EXPECT_EQ(r_num_mss, variant->r_num_mss);
958 }
959 
960 TEST_F(tun_vnet_udptnl, recv_gso_packet)
961 {
962 	struct virtio_net_hdr_v1_hash_tunnel vnet_hdr = { 0 };
963 	struct virtio_net_hdr_v1 *vh = &vnet_hdr.hash_hdr.hdr;
964 	int ret, gso_type = VIRTIO_NET_HDR_GSO_UDP_L4;
965 
966 	ret = send_gso_packet_into_tunnel(self, variant);
967 	EXPECT_EQ(ret, variant->data_size);
968 
969 	memset(&vnet_hdr, 0, sizeof(vnet_hdr));
970 	ret = receive_gso_packet_from_tun(self, variant, &vnet_hdr);
971 	EXPECT_EQ(ret, variant->data_size);
972 
973 	if (!variant->no_gso) {
974 		EXPECT_EQ(vh->gso_size, variant->gso_size);
975 		gso_type |= (variant->tunnel_type & UDP_TUNNEL_OUTER_IPV4) ?
976 				    (VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV4) :
977 				    (VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV6);
978 		EXPECT_EQ(vh->gso_type, gso_type);
979 	}
980 }
981 
982 XFAIL_ADD(tun_vnet_udptnl, 4in4_nogsosz_gtmss, recv_gso_packet);
983 XFAIL_ADD(tun_vnet_udptnl, 6in4_nogsosz_gtmss, recv_gso_packet);
984 XFAIL_ADD(tun_vnet_udptnl, 4in6_nogsosz_gtmss, recv_gso_packet);
985 XFAIL_ADD(tun_vnet_udptnl, 6in6_nogsosz_gtmss, recv_gso_packet);
986 
987 XFAIL_ADD(tun_vnet_udptnl, 4in4_over_maxbytes, send_gso_packet);
988 XFAIL_ADD(tun_vnet_udptnl, 6in4_over_maxbytes, send_gso_packet);
989 XFAIL_ADD(tun_vnet_udptnl, 4in6_over_maxbytes, send_gso_packet);
990 XFAIL_ADD(tun_vnet_udptnl, 6in6_over_maxbytes, send_gso_packet);
991 
992 XFAIL_ADD(tun_vnet_udptnl, 4in4_over_maxbytes, recv_gso_packet);
993 XFAIL_ADD(tun_vnet_udptnl, 6in4_over_maxbytes, recv_gso_packet);
994 XFAIL_ADD(tun_vnet_udptnl, 4in6_over_maxbytes, recv_gso_packet);
995 XFAIL_ADD(tun_vnet_udptnl, 6in6_over_maxbytes, recv_gso_packet);
996 
997 TEST_HARNESS_MAIN
998