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 ¶m_ipaddr4_outer_src, 585 ¶m_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 *)¶m_ipaddr4_outer_src, 597 sizeof(param_ipaddr4_outer_src)); 598 sum += add_csum((const uint8_t *)¶m_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 *)¶m_ipaddr4_outer_src; 810 *dstip = (void *)¶m_ipaddr4_outer_dst; 811 } else { 812 *srcip = (void *)¶m_ipaddr6_outer_src; 813 *dstip = (void *)¶m_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 *)¶m_ipaddr4_inner_src; 820 *dstip = (void *)¶m_ipaddr4_inner_dst; 821 } else { 822 *srcip = (void *)¶m_ipaddr6_inner_src; 823 *dstip = (void *)¶m_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