xref: /linux/tools/testing/selftests/net/tun.c (revision ee2d4c2d7cc18a2cd504044a75ea614e720248eb)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #define _GNU_SOURCE
4 
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <linux/if_tun.h>
12 #include <netinet/tcp.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 	memset(self->ifname, 0, sizeof(self->ifname));
493 
494 	self->fd = tun_alloc(self->ifname);
495 	ASSERT_GE(self->fd, 0);
496 
497 	self->fd2 = tun_alloc(self->ifname);
498 	ASSERT_GE(self->fd2, 0);
499 }
500 
501 FIXTURE_TEARDOWN(tun)
502 {
503 	if (self->fd >= 0)
504 		close(self->fd);
505 	if (self->fd2 >= 0)
506 		close(self->fd2);
507 }
508 
509 TEST_F(tun, delete_detach_close)
510 {
511 	EXPECT_EQ(tun_delete(self->ifname), 0);
512 	EXPECT_EQ(tun_detach(self->fd, self->ifname), -1);
513 	EXPECT_EQ(errno, 22);
514 }
515 
516 TEST_F(tun, detach_delete_close)
517 {
518 	EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
519 	EXPECT_EQ(tun_delete(self->ifname), 0);
520 }
521 
522 TEST_F(tun, detach_close_delete)
523 {
524 	EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
525 	close(self->fd);
526 	self->fd = -1;
527 	EXPECT_EQ(tun_delete(self->ifname), 0);
528 }
529 
530 TEST_F(tun, reattach_delete_close)
531 {
532 	EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
533 	EXPECT_EQ(tun_attach(self->fd, self->ifname), 0);
534 	EXPECT_EQ(tun_delete(self->ifname), 0);
535 }
536 
537 TEST_F(tun, reattach_close_delete)
538 {
539 	EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
540 	EXPECT_EQ(tun_attach(self->fd, self->ifname), 0);
541 	close(self->fd);
542 	self->fd = -1;
543 	EXPECT_EQ(tun_delete(self->ifname), 0);
544 }
545 
546 FIXTURE(tun_vnet_gso)
547 {
548 	char ifname[IFNAMSIZ];
549 	int fd;
550 };
551 
552 FIXTURE_SETUP(tun_vnet_gso)
553 {
554 	int flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
555 
556 	memset(self->ifname, 0, sizeof(self->ifname));
557 	self->fd = tun_open(self->ifname, flags, 0, 0, NULL);
558 	ASSERT_GE(self->fd, 0);
559 }
560 
561 FIXTURE_TEARDOWN(tun_vnet_gso)
562 {
563 	if (self->fd >= 0)
564 		close(self->fd);
565 }
566 
567 static int build_vlan_tcpv4_gso_packet(uint8_t *buf, int payload_len)
568 {
569 	uint16_t vlan_tag[2] = { htons(100), htons(ETH_P_IP) };
570 	uint8_t *cur = buf + sizeof(struct virtio_net_hdr);
571 	struct virtio_net_hdr vh = { 0 };
572 	struct tcphdr tcph = { 0 };
573 	uint32_t sum;
574 
575 	cur += build_eth(cur, ETH_P_8021Q, param_hwaddr_outer_src,
576 			 param_hwaddr_outer_dst);
577 
578 	/* 802.1Q tag: VID=100, inner protocol=ETH_P_IP */
579 	memcpy(cur, vlan_tag, sizeof(vlan_tag));
580 	cur += sizeof(vlan_tag);
581 
582 	cur += build_ipv4_header(cur, IPPROTO_TCP,
583 				 sizeof(tcph) + payload_len,
584 				 &param_ipaddr4_outer_src,
585 				 &param_ipaddr4_outer_dst);
586 
587 	tcph.source = htons(12345);
588 	tcph.dest = htons(80);
589 	tcph.seq = htonl(1);
590 	tcph.doff = sizeof(tcph) / 4;
591 	tcph.ack = 1;
592 	tcph.window = htons(65535);
593 	memcpy(cur, &tcph, sizeof(tcph));
594 	memset(cur + sizeof(tcph), PKT_DATA, payload_len);
595 
596 	sum = add_csum((const uint8_t *)&param_ipaddr4_outer_src,
597 		       sizeof(param_ipaddr4_outer_src));
598 	sum += add_csum((const uint8_t *)&param_ipaddr4_outer_dst,
599 			sizeof(param_ipaddr4_outer_dst));
600 	sum += htons(IPPROTO_TCP) + htons(sizeof(tcph) + payload_len);
601 	sum += add_csum(cur, sizeof(tcph) + payload_len);
602 	tcph.check = finish_ip_csum(sum);
603 	memcpy(cur, &tcph, sizeof(tcph));
604 	cur += sizeof(tcph) + payload_len;
605 
606 	vh.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
607 	vh.gso_size = 1400;
608 	vh.hdr_len = (cur - buf) - sizeof(vh) - payload_len;
609 	memcpy(buf, &vh, sizeof(vh));
610 
611 	return cur - buf;
612 }
613 
614 TEST_F(tun_vnet_gso, vlan_tcpv4_gso_no_csum)
615 {
616 	struct virtio_net_hdr vh;
617 	uint8_t pkt[4096] = { 0 };
618 	int len, ret;
619 
620 	len = build_vlan_tcpv4_gso_packet(pkt, 2800);
621 	memcpy(&vh, pkt, sizeof(vh));
622 
623 	/* Valid VLAN-tagged TCPv4 GSO with flags = 0 (no NEEDS_CSUM) */
624 	vh.flags = 0;
625 	memcpy(pkt, &vh, sizeof(vh));
626 	ret = write(self->fd, pkt, len);
627 	ASSERT_EQ(ret, len);
628 
629 	/* Valid VLAN-tagged TCPv4 GSO with flags = DATA_VALID */
630 	vh.flags = VIRTIO_NET_HDR_F_DATA_VALID;
631 	memcpy(pkt, &vh, sizeof(vh));
632 	ret = write(self->fd, pkt, len);
633 	ASSERT_EQ(ret, len);
634 
635 	/* Mismatched GSO type (TCPV6 on VLAN-tagged IPv4 packet) */
636 	vh.flags = 0;
637 	vh.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
638 	memcpy(pkt, &vh, sizeof(vh));
639 	ret = write(self->fd, pkt, len);
640 	ASSERT_EQ(ret, -1);
641 	ASSERT_EQ(errno, EINVAL);
642 
643 	/* TCP header truncated after 10 bytes, without NEEDS_CSUM.
644 	 * Requires the transport header offset found by flow dissection:
645 	 * pulling only sizeof(struct iphdr) + sizeof(struct tcphdr) bytes
646 	 * from the mac header would accept this frame.
647 	 */
648 	vh.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
649 	vh.hdr_len = ETH_HLEN + 4 + sizeof(struct iphdr) + 10;
650 	memcpy(pkt, &vh, sizeof(vh));
651 	ret = write(self->fd, pkt, sizeof(vh) + vh.hdr_len);
652 	ASSERT_EQ(ret, -1);
653 	ASSERT_EQ(errno, EINVAL);
654 }
655 
656 TEST_F(tun_vnet_gso, vlan_tcpv4_gso_no_csum_64k)
657 {
658 	/* Ethernet frame of 65540 bytes: skb->len is above U16_MAX when the
659 	 * frame is flow-dissected, before eth_type_trans() pulls ETH_HLEN.
660 	 */
661 	const int payload_len = 65540 - ETH_HLEN - 4 -
662 				sizeof(struct iphdr) - sizeof(struct tcphdr);
663 	struct virtio_net_hdr vh;
664 	uint8_t *pkt;
665 	int len, ret;
666 
667 	pkt = calloc(1, sizeof(vh) + 65540);
668 	ASSERT_NE(pkt, NULL);
669 
670 	len = build_vlan_tcpv4_gso_packet(pkt, payload_len);
671 	ASSERT_EQ(len, sizeof(vh) + 65540);
672 	memcpy(&vh, pkt, sizeof(vh));
673 
674 	vh.flags = 0;
675 	memcpy(pkt, &vh, sizeof(vh));
676 	ret = write(self->fd, pkt, len);
677 	free(pkt);
678 	ASSERT_EQ(ret, len);
679 }
680 
681 FIXTURE(tun_vnet_udptnl)
682 {
683 	char ifname[IFNAMSIZ];
684 	int fd, sock;
685 };
686 
687 FIXTURE_VARIANT(tun_vnet_udptnl)
688 {
689 	int tunnel_type;
690 	int gso_size;
691 	int data_size;
692 	int r_num_mss;
693 	bool is_tap, no_gso;
694 };
695 
696 /* clang-format off */
697 #define TUN_VNET_UDPTNL_VARIANT_ADD(type, desc)                              \
698 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_nogsosz_1byte) {         \
699 		/* no GSO: send a single byte */                             \
700 		.tunnel_type = type,                                         \
701 		.data_size = 1,                                              \
702 		.r_num_mss = 1,                                              \
703 		.is_tap = true,                                              \
704 		.no_gso = true,                                              \
705 	};                                                                   \
706 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_nogsosz_1mss) {          \
707 		/* no GSO: send a single MSS, fall back to no GSO */         \
708 		.tunnel_type = type,                                         \
709 		.data_size = UDP_TUNNEL_MSS(type),                           \
710 		.r_num_mss = 1,                                              \
711 		.is_tap = true,                                              \
712 		.no_gso = true,                                              \
713 	};                                                                   \
714 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_nogsosz_gtmss) {         \
715 		/* no GSO: send a single MSS + 1B: fail */                   \
716 		.tunnel_type = type,                                         \
717 		.data_size = UDP_TUNNEL_MSS(type) + 1,                       \
718 		.r_num_mss = 1,                                              \
719 		.is_tap = true,                                              \
720 		.no_gso = true,                                              \
721 	};                                                                   \
722 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_1byte) {                 \
723 		/* GSO: send 1 byte, gso 1 byte, fall back to no GSO */      \
724 		.tunnel_type = type,                                         \
725 		.gso_size = 1,                                               \
726 		.data_size = 1,                                              \
727 		.r_num_mss = 1,                                              \
728 		.is_tap = true,                                              \
729 		.no_gso = true,                                              \
730 	};                                                                   \
731 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_1mss) {                  \
732 		/* send a single MSS: fall back to no GSO */                 \
733 		.tunnel_type = type,                                         \
734 		.gso_size = UDP_TUNNEL_MSS(type),                            \
735 		.data_size = UDP_TUNNEL_MSS(type),                           \
736 		.r_num_mss = 1,                                              \
737 		.is_tap = true,                                              \
738 		.no_gso = true,                                              \
739 	};                                                                   \
740 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_ltgso) {                 \
741 		/* data <= MSS < gso: will fall back to no GSO */            \
742 		.tunnel_type = type,                                         \
743 		.gso_size = UDP_TUNNEL_MSS(type) + 1,                        \
744 		.data_size = UDP_TUNNEL_MSS(type),                           \
745 		.r_num_mss = 1,                                              \
746 		.is_tap = true,                                              \
747 		.no_gso = true,                                              \
748 	};                                                                   \
749 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_gtgso) {                 \
750 		/* GSO: a single MSS + 1B */                                 \
751 		.tunnel_type = type,                                         \
752 		.gso_size = UDP_TUNNEL_MSS(type),                            \
753 		.data_size = UDP_TUNNEL_MSS(type) + 1,                       \
754 		.r_num_mss = 2,                                              \
755 		.is_tap = true,                                              \
756 	};                                                                   \
757 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_2mss) {                  \
758 		/* no GSO: send exactly 2 MSS */                             \
759 		.tunnel_type = type,                                         \
760 		.gso_size = UDP_TUNNEL_MSS(type),                            \
761 		.data_size = UDP_TUNNEL_MSS(type) * 2,                       \
762 		.r_num_mss = 2,                                              \
763 		.is_tap = true,                                              \
764 	};                                                                   \
765 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_maxbytes) {              \
766 		/* GSO: send max bytes */                                    \
767 		.tunnel_type = type,                                         \
768 		.gso_size = UDP_TUNNEL_MSS(type),                            \
769 		.data_size = UDP_TUNNEL_MAX(type, true),                     \
770 		.r_num_mss = UDP_TUNNEL_MAX(type, true) /                    \
771 			     UDP_TUNNEL_MSS(type) + 1,                       \
772 		.is_tap = true,                                              \
773 	};                                                                   \
774 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_over_maxbytes) {         \
775 		/* GSO: send oversize max bytes: fail */                     \
776 		.tunnel_type = type,                                         \
777 		.gso_size = UDP_TUNNEL_MSS(type),                            \
778 		.data_size = ETH_MAX_MTU,                                    \
779 		.r_num_mss = ETH_MAX_MTU / UDP_TUNNEL_MSS(type) + 1,         \
780 		.is_tap = true,                                              \
781 	};                                                                   \
782 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_maxsegs) {               \
783 		/* GSO: send max number of min sized segments */             \
784 		.tunnel_type = type,                                         \
785 		.gso_size = 1,                                               \
786 		.data_size = UDP_TUNNEL_MAX_SEGMENTS,                        \
787 		.r_num_mss = UDP_TUNNEL_MAX_SEGMENTS,                        \
788 		.is_tap = true,                                              \
789 	};                                                                   \
790 	FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_5byte) {                 \
791 		/* GSO: send 5 bytes, gso 2 bytes */                         \
792 		.tunnel_type = type,                                         \
793 		.gso_size = 2,                                               \
794 		.data_size = 5,                                              \
795 		.r_num_mss = 3,                                              \
796 		.is_tap = true,                                              \
797 	} /* clang-format on */
798 
799 TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_4IN4, 4in4);
800 TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_6IN4, 6in4);
801 TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_4IN6, 4in6);
802 TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_6IN6, 6in6);
803 
804 static void assign_ifaddr_vars(int family, int is_outer, void **srcip,
805 			       void **dstip, void **srcmac, void **dstmac)
806 {
807 	if (is_outer) {
808 		if (family == AF_INET) {
809 			*srcip = (void *)&param_ipaddr4_outer_src;
810 			*dstip = (void *)&param_ipaddr4_outer_dst;
811 		} else {
812 			*srcip = (void *)&param_ipaddr6_outer_src;
813 			*dstip = (void *)&param_ipaddr6_outer_dst;
814 		}
815 		*srcmac = param_hwaddr_outer_src;
816 		*dstmac = param_hwaddr_outer_dst;
817 	} else {
818 		if (family == AF_INET) {
819 			*srcip = (void *)&param_ipaddr4_inner_src;
820 			*dstip = (void *)&param_ipaddr4_inner_dst;
821 		} else {
822 			*srcip = (void *)&param_ipaddr6_inner_src;
823 			*dstip = (void *)&param_ipaddr6_inner_dst;
824 		}
825 		*srcmac = param_hwaddr_inner_src;
826 		*dstmac = param_hwaddr_inner_dst;
827 	}
828 }
829 
830 static void assign_sockaddr_vars(int family, int is_outer,
831 				 struct sockaddr_storage *src,
832 				 struct sockaddr_storage *dst)
833 {
834 	src->ss_family = family;
835 	dst->ss_family = family;
836 
837 	if (family == AF_INET) {
838 		struct sockaddr_in *s4 = (struct sockaddr_in *)src;
839 		struct sockaddr_in *d4 = (struct sockaddr_in *)dst;
840 
841 		s4->sin_addr = is_outer ? param_ipaddr4_outer_src :
842 					  param_ipaddr4_inner_src;
843 		d4->sin_addr = is_outer ? param_ipaddr4_outer_dst :
844 					  param_ipaddr4_inner_dst;
845 		if (!is_outer) {
846 			s4->sin_port = htons(UDP_SRC_PORT);
847 			d4->sin_port = htons(UDP_DST_PORT);
848 		}
849 	} else {
850 		struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)src;
851 		struct sockaddr_in6 *d6 = (struct sockaddr_in6 *)dst;
852 
853 		s6->sin6_addr = is_outer ? param_ipaddr6_outer_src :
854 					   param_ipaddr6_inner_src;
855 		d6->sin6_addr = is_outer ? param_ipaddr6_outer_dst :
856 					   param_ipaddr6_inner_dst;
857 		if (!is_outer) {
858 			s6->sin6_port = htons(UDP_SRC_PORT);
859 			d6->sin6_port = htons(UDP_DST_PORT);
860 		}
861 	}
862 }
863 
864 FIXTURE_SETUP(tun_vnet_udptnl)
865 {
866 	int ret, family, prefix, flags, features;
867 	int tunnel_type = variant->tunnel_type;
868 	struct sockaddr_storage ssa, dsa;
869 	void *sip, *dip, *smac, *dmac;
870 
871 	flags = (variant->is_tap ? IFF_TAP : IFF_TUN) | IFF_VNET_HDR |
872 		IFF_MULTI_QUEUE | IFF_NO_PI;
873 	features = TUN_F_CSUM | TUN_F_UDP_TUNNEL_GSO |
874 		   TUN_F_UDP_TUNNEL_GSO_CSUM | TUN_F_USO4 | TUN_F_USO6;
875 	self->fd = tun_open(self->ifname, flags, TUN_VNET_TNL_SIZE, features,
876 			    param_hwaddr_outer_src);
877 	ASSERT_GE(self->fd, 0);
878 
879 	family = (tunnel_type & UDP_TUNNEL_OUTER_IPV4) ? AF_INET : AF_INET6;
880 	prefix = (family == AF_INET) ? IPPREFIX_LEN : IP6PREFIX_LEN;
881 	assign_ifaddr_vars(family, 1, &sip, &dip, &smac, &dmac);
882 
883 	ret = ip_addr_add(self->ifname, family, sip, prefix);
884 	ASSERT_EQ(ret, 0);
885 	ret = ip_neigh_add(self->ifname, family, dip, dmac);
886 	ASSERT_EQ(ret, 0);
887 	ret = ip_route_check(self->ifname, family, sip);
888 	ASSERT_EQ(ret, 0);
889 
890 	ret = geneve_create(param_dev_geneve_name, family, dip,
891 			    param_hwaddr_inner_src);
892 	ASSERT_EQ(ret, 0);
893 
894 	family = (tunnel_type & UDP_TUNNEL_INNER_IPV4) ? AF_INET : AF_INET6;
895 	prefix = (family == AF_INET) ? IPPREFIX_LEN : IP6PREFIX_LEN;
896 	assign_ifaddr_vars(family, 0, &sip, &dip, &smac, &dmac);
897 
898 	ret = ip_addr_add(param_dev_geneve_name, family, sip, prefix);
899 	ASSERT_EQ(ret, 0);
900 	ret = ip_neigh_add(param_dev_geneve_name, family, dip, dmac);
901 	ASSERT_EQ(ret, 0);
902 	ret = ip_route_check(param_dev_geneve_name, family, sip);
903 	ASSERT_EQ(ret, 0);
904 
905 	assign_sockaddr_vars(family, 0, &ssa, &dsa);
906 	self->sock = udp_socket_open(&ssa, false, true, &dsa);
907 	ASSERT_GE(self->sock, 0);
908 }
909 
910 FIXTURE_TEARDOWN(tun_vnet_udptnl)
911 {
912 	int ret;
913 
914 	if (self->sock != -1)
915 		close(self->sock);
916 
917 	ret = ip_link_del(param_dev_geneve_name);
918 	EXPECT_EQ(ret, 0);
919 
920 	ret = tun_delete(self->ifname);
921 	EXPECT_EQ(ret, 0);
922 }
923 
924 static int build_gso_packet_into_tun(const FIXTURE_VARIANT(tun_vnet_udptnl) *
925 					     variant,
926 				     uint8_t *buf)
927 {
928 	int pktlen, hlen, proto, inner_family, outer_family;
929 	int tunnel_type = variant->tunnel_type;
930 	int payload_len = variant->data_size;
931 	int gso_size = variant->gso_size;
932 	uint8_t *outer_udph, *cur = buf;
933 	void *sip, *dip, *smac, *dmac;
934 	bool is_tap = variant->is_tap;
935 
936 	hlen = (is_tap ? ETH_HLEN : 0) + UDP_TUNNEL_HDRLEN(tunnel_type);
937 	inner_family = (tunnel_type & UDP_TUNNEL_INNER_IPV4) ? AF_INET :
938 							       AF_INET6;
939 	outer_family = (tunnel_type & UDP_TUNNEL_OUTER_IPV4) ? AF_INET :
940 							       AF_INET6;
941 
942 	cur += build_virtio_net_hdr_v1_hash_tunnel(cur, is_tap, hlen, gso_size,
943 						   outer_family, inner_family);
944 
945 	pktlen = hlen + payload_len;
946 	assign_ifaddr_vars(outer_family, 1, &sip, &dip, &smac, &dmac);
947 
948 	if (is_tap) {
949 		proto = outer_family == AF_INET ? ETH_P_IP : ETH_P_IPV6;
950 		pktlen -= ETH_HLEN;
951 		cur += build_eth(cur, proto, dmac, smac);
952 	}
953 
954 	if (outer_family == AF_INET) {
955 		pktlen = pktlen - sizeof(struct iphdr);
956 		cur += build_ipv4_header(cur, IPPROTO_UDP, pktlen, dip, sip);
957 	} else {
958 		pktlen = pktlen - sizeof(struct ipv6hdr);
959 		cur += build_ipv6_header(cur, IPPROTO_UDP, 0, pktlen, dip, sip);
960 	}
961 
962 	outer_udph = cur;
963 	assign_ifaddr_vars(inner_family, 0, &sip, &dip, &smac, &dmac);
964 
965 	pktlen -= sizeof(struct udphdr);
966 	proto = inner_family == AF_INET ? ETH_P_IP : ETH_P_IPV6;
967 	cur += build_udp_header(cur, UDP_SRC_PORT, VN_PORT, pktlen);
968 	cur += build_geneve_header(cur, VN_ID);
969 	cur += build_eth(cur, proto, dmac, smac);
970 
971 	pktlen = sizeof(struct udphdr) + payload_len;
972 	if (inner_family == AF_INET)
973 		cur += build_ipv4_header(cur, IPPROTO_UDP, pktlen, dip, sip);
974 	else
975 		cur += build_ipv6_header(cur, IPPROTO_UDP, 0, pktlen, dip, sip);
976 
977 	cur += build_udp_packet(cur, UDP_DST_PORT, UDP_SRC_PORT, payload_len,
978 				inner_family, false);
979 
980 	build_udp_packet_csum(outer_udph, outer_family, false);
981 
982 	return cur - buf;
983 }
984 
985 static int
986 receive_gso_packet_from_tunnel(FIXTURE_DATA(tun_vnet_udptnl) * self,
987 			       const FIXTURE_VARIANT(tun_vnet_udptnl) * variant,
988 			       int *r_num_mss)
989 {
990 	uint8_t packet_buf[MAX_VNET_TUNNEL_PACKET_SZ];
991 	int len, total_len = 0, socket = self->sock;
992 	int payload_len = variant->data_size;
993 
994 	while (total_len < payload_len) {
995 		len = recv(socket, packet_buf, sizeof(packet_buf), 0);
996 		if (len <= 0) {
997 			if (len < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
998 				perror("recv");
999 			break;
1000 		}
1001 
1002 		(*r_num_mss)++;
1003 		total_len += len;
1004 	}
1005 
1006 	return total_len;
1007 }
1008 
1009 static int send_gso_packet_into_tunnel(FIXTURE_DATA(tun_vnet_udptnl) * self,
1010 				       const FIXTURE_VARIANT(tun_vnet_udptnl) *
1011 					       variant)
1012 {
1013 	int family = (variant->tunnel_type & UDP_TUNNEL_INNER_IPV4) ? AF_INET :
1014 								      AF_INET6;
1015 	uint8_t buf[MAX_VNET_TUNNEL_PACKET_SZ] = { 0 };
1016 	int payload_len = variant->data_size;
1017 	int gso_size = variant->gso_size;
1018 	struct sockaddr_storage ssa, dsa;
1019 
1020 	assign_sockaddr_vars(family, 0, &ssa, &dsa);
1021 	return send_gso_udp_msg(self->sock, &dsa, buf, payload_len, gso_size);
1022 }
1023 
1024 static int
1025 receive_gso_packet_from_tun(FIXTURE_DATA(tun_vnet_udptnl) * self,
1026 			    const FIXTURE_VARIANT(tun_vnet_udptnl) * variant,
1027 			    struct virtio_net_hdr_v1_hash_tunnel *vnet_hdr)
1028 {
1029 	struct timeval timeout = { .tv_sec = TIMEOUT_SEC };
1030 	uint8_t buf[MAX_VNET_TUNNEL_PACKET_SZ];
1031 	int tunnel_type = variant->tunnel_type;
1032 	int payload_len = variant->data_size;
1033 	bool is_tap = variant->is_tap;
1034 	int ret, len, total_len = 0;
1035 	int tun_fd = self->fd;
1036 	fd_set fdset;
1037 
1038 	while (total_len < payload_len) {
1039 		FD_ZERO(&fdset);
1040 		FD_SET(tun_fd, &fdset);
1041 
1042 		ret = select(tun_fd + 1, &fdset, NULL, NULL, &timeout);
1043 		if (ret <= 0) {
1044 			perror("select");
1045 			break;
1046 		}
1047 		if (!FD_ISSET(tun_fd, &fdset))
1048 			continue;
1049 
1050 		len = read(tun_fd, buf, sizeof(buf));
1051 		if (len <= 0) {
1052 			if (len < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
1053 				perror("read");
1054 			break;
1055 		}
1056 
1057 		len = parse_udp_tunnel_vnet_packet(buf, len, tunnel_type,
1058 						   is_tap);
1059 		if (len < 0)
1060 			continue;
1061 
1062 		if (total_len == 0)
1063 			memcpy(vnet_hdr, buf, TUN_VNET_TNL_SIZE);
1064 
1065 		total_len += len;
1066 	}
1067 
1068 	return total_len;
1069 }
1070 
1071 TEST_F(tun_vnet_udptnl, send_gso_packet)
1072 {
1073 	uint8_t pkt[MAX_VNET_TUNNEL_PACKET_SZ];
1074 	int r_num_mss = 0;
1075 	int ret, off;
1076 
1077 	memset(pkt, 0, sizeof(pkt));
1078 	off = build_gso_packet_into_tun(variant, pkt);
1079 	ret = write(self->fd, pkt, off);
1080 	ASSERT_EQ(ret, off);
1081 
1082 	ret = receive_gso_packet_from_tunnel(self, variant, &r_num_mss);
1083 	EXPECT_EQ(ret, variant->data_size);
1084 	EXPECT_EQ(r_num_mss, variant->r_num_mss);
1085 }
1086 
1087 TEST_F(tun_vnet_udptnl, recv_gso_packet)
1088 {
1089 	struct virtio_net_hdr_v1_hash_tunnel vnet_hdr = { 0 };
1090 	struct virtio_net_hdr_v1 *vh = &vnet_hdr.hash_hdr.hdr;
1091 	int ret, gso_type = VIRTIO_NET_HDR_GSO_UDP_L4;
1092 
1093 	ret = send_gso_packet_into_tunnel(self, variant);
1094 	EXPECT_EQ(ret, variant->data_size);
1095 
1096 	memset(&vnet_hdr, 0, sizeof(vnet_hdr));
1097 	ret = receive_gso_packet_from_tun(self, variant, &vnet_hdr);
1098 	EXPECT_EQ(ret, variant->data_size);
1099 
1100 	if (!variant->no_gso) {
1101 		EXPECT_EQ(vh->gso_size, variant->gso_size);
1102 		gso_type |= (variant->tunnel_type & UDP_TUNNEL_OUTER_IPV4) ?
1103 				    (VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV4) :
1104 				    (VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV6);
1105 		EXPECT_EQ(vh->gso_type, gso_type);
1106 	}
1107 }
1108 
1109 XFAIL_ADD(tun_vnet_udptnl, 4in4_nogsosz_gtmss, recv_gso_packet);
1110 XFAIL_ADD(tun_vnet_udptnl, 6in4_nogsosz_gtmss, recv_gso_packet);
1111 XFAIL_ADD(tun_vnet_udptnl, 4in6_nogsosz_gtmss, recv_gso_packet);
1112 XFAIL_ADD(tun_vnet_udptnl, 6in6_nogsosz_gtmss, recv_gso_packet);
1113 
1114 XFAIL_ADD(tun_vnet_udptnl, 4in4_over_maxbytes, send_gso_packet);
1115 XFAIL_ADD(tun_vnet_udptnl, 6in4_over_maxbytes, send_gso_packet);
1116 XFAIL_ADD(tun_vnet_udptnl, 4in6_over_maxbytes, send_gso_packet);
1117 XFAIL_ADD(tun_vnet_udptnl, 6in6_over_maxbytes, send_gso_packet);
1118 
1119 XFAIL_ADD(tun_vnet_udptnl, 4in4_over_maxbytes, recv_gso_packet);
1120 XFAIL_ADD(tun_vnet_udptnl, 6in4_over_maxbytes, recv_gso_packet);
1121 XFAIL_ADD(tun_vnet_udptnl, 4in6_over_maxbytes, recv_gso_packet);
1122 XFAIL_ADD(tun_vnet_udptnl, 6in6_over_maxbytes, recv_gso_packet);
1123 
1124 TEST_HARNESS_MAIN
1125