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