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 ¶m_ipaddr4_outer_src, 590 ¶m_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 *)¶m_ipaddr4_outer_src, 602 sizeof(param_ipaddr4_outer_src)); 603 sum += add_csum((const uint8_t *)¶m_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 *)¶m_ipaddr4_outer_src; 815 *dstip = (void *)¶m_ipaddr4_outer_dst; 816 } else { 817 *srcip = (void *)¶m_ipaddr6_outer_src; 818 *dstip = (void *)¶m_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 *)¶m_ipaddr4_inner_src; 825 *dstip = (void *)¶m_ipaddr4_inner_dst; 826 } else { 827 *srcip = (void *)¶m_ipaddr6_inner_src; 828 *dstip = (void *)¶m_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