1 /* 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Licensed under the GPL 4 */ 5 6 #include <stdio.h> 7 #include <unistd.h> 8 #include <stdarg.h> 9 #include <errno.h> 10 #include <stddef.h> 11 #include <string.h> 12 #include <sys/ioctl.h> 13 #include <net/if.h> 14 #include <linux/if_tun.h> 15 #include <arpa/inet.h> 16 #include <sys/types.h> 17 #include <sys/stat.h> 18 #include <fcntl.h> 19 #include <sys/socket.h> 20 #include <net/ethernet.h> 21 #include <netinet/ip.h> 22 #include <netinet/ether.h> 23 #include <linux/if_ether.h> 24 #include <linux/if_packet.h> 25 #include <sys/wait.h> 26 #include <sys/uio.h> 27 #include <linux/virtio_net.h> 28 #include <netdb.h> 29 #include <stdlib.h> 30 #include <os.h> 31 #include <um_malloc.h> 32 #include "vector_user.h" 33 34 #define ID_GRE 0 35 #define ID_L2TPV3 1 36 #define ID_MAX 1 37 38 #define TOKEN_IFNAME "ifname" 39 40 #define TRANS_RAW "raw" 41 #define TRANS_RAW_LEN strlen(TRANS_RAW) 42 43 #define VNET_HDR_FAIL "could not enable vnet headers on fd %d" 44 #define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s" 45 #define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i" 46 #define BPF_ATTACH_FAIL "Failed to attach filter size %d to %d, err %d\n" 47 48 /* This is very ugly and brute force lookup, but it is done 49 * only once at initialization so not worth doing hashes or 50 * anything more intelligent 51 */ 52 53 char *uml_vector_fetch_arg(struct arglist *ifspec, char *token) 54 { 55 int i; 56 57 for (i = 0; i < ifspec->numargs; i++) { 58 if (strcmp(ifspec->tokens[i], token) == 0) 59 return ifspec->values[i]; 60 } 61 return NULL; 62 63 } 64 65 struct arglist *uml_parse_vector_ifspec(char *arg) 66 { 67 struct arglist *result; 68 int pos, len; 69 bool parsing_token = true, next_starts = true; 70 71 if (arg == NULL) 72 return NULL; 73 result = uml_kmalloc(sizeof(struct arglist), UM_GFP_KERNEL); 74 if (result == NULL) 75 return NULL; 76 result->numargs = 0; 77 len = strlen(arg); 78 for (pos = 0; pos < len; pos++) { 79 if (next_starts) { 80 if (parsing_token) { 81 result->tokens[result->numargs] = arg + pos; 82 } else { 83 result->values[result->numargs] = arg + pos; 84 result->numargs++; 85 } 86 next_starts = false; 87 } 88 if (*(arg + pos) == '=') { 89 if (parsing_token) 90 parsing_token = false; 91 else 92 goto cleanup; 93 next_starts = true; 94 (*(arg + pos)) = '\0'; 95 } 96 if (*(arg + pos) == ',') { 97 parsing_token = true; 98 next_starts = true; 99 (*(arg + pos)) = '\0'; 100 } 101 } 102 return result; 103 cleanup: 104 printk(UM_KERN_ERR "vector_setup - Couldn't parse '%s'\n", arg); 105 kfree(result); 106 return NULL; 107 } 108 109 /* 110 * Socket/FD configuration functions. These return an structure 111 * of rx and tx descriptors to cover cases where these are not 112 * the same (f.e. read via raw socket and write via tap). 113 */ 114 115 #define PATH_NET_TUN "/dev/net/tun" 116 117 static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) 118 { 119 struct ifreq ifr; 120 int fd = -1; 121 struct sockaddr_ll sock; 122 int err = -ENOMEM, offload; 123 char *iface; 124 struct vector_fds *result = NULL; 125 126 iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); 127 if (iface == NULL) { 128 printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n"); 129 goto tap_cleanup; 130 } 131 132 result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); 133 if (result == NULL) { 134 printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n"); 135 goto tap_cleanup; 136 } 137 result->rx_fd = -1; 138 result->tx_fd = -1; 139 result->remote_addr = NULL; 140 result->remote_addr_size = 0; 141 142 /* TAP */ 143 144 fd = open(PATH_NET_TUN, O_RDWR); 145 if (fd < 0) { 146 printk(UM_KERN_ERR "uml_tap: failed to open tun device\n"); 147 goto tap_cleanup; 148 } 149 result->tx_fd = fd; 150 memset(&ifr, 0, sizeof(ifr)); 151 ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR; 152 strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); 153 154 err = ioctl(fd, TUNSETIFF, (void *) &ifr); 155 if (err != 0) { 156 printk(UM_KERN_ERR "uml_tap: failed to select tap interface\n"); 157 goto tap_cleanup; 158 } 159 160 offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6; 161 ioctl(fd, TUNSETOFFLOAD, offload); 162 163 /* RAW */ 164 165 fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 166 if (fd == -1) { 167 printk(UM_KERN_ERR 168 "uml_tap: failed to create socket: %i\n", -errno); 169 goto tap_cleanup; 170 } 171 result->rx_fd = fd; 172 memset(&ifr, 0, sizeof(ifr)); 173 strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); 174 if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) { 175 printk(UM_KERN_ERR 176 "uml_tap: failed to set interface: %i\n", -errno); 177 goto tap_cleanup; 178 } 179 180 sock.sll_family = AF_PACKET; 181 sock.sll_protocol = htons(ETH_P_ALL); 182 sock.sll_ifindex = ifr.ifr_ifindex; 183 184 if (bind(fd, 185 (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { 186 printk(UM_KERN_ERR 187 "user_init_tap: failed to bind raw pair, err %d\n", 188 -errno); 189 goto tap_cleanup; 190 } 191 return result; 192 tap_cleanup: 193 printk(UM_KERN_ERR "user_init_tap: init failed, error %d", err); 194 if (result != NULL) { 195 if (result->rx_fd >= 0) 196 os_close_file(result->rx_fd); 197 if (result->tx_fd >= 0) 198 os_close_file(result->tx_fd); 199 kfree(result); 200 } 201 return NULL; 202 } 203 204 205 static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) 206 { 207 struct ifreq ifr; 208 int rxfd = -1, txfd = -1; 209 struct sockaddr_ll sock; 210 int err = -ENOMEM; 211 char *iface; 212 struct vector_fds *result = NULL; 213 214 iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); 215 if (iface == NULL) 216 goto cleanup; 217 218 rxfd = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); 219 if (rxfd == -1) { 220 err = -errno; 221 goto cleanup; 222 } 223 txfd = socket(AF_PACKET, SOCK_RAW, 0); /* Turn off RX on this fd */ 224 if (txfd == -1) { 225 err = -errno; 226 goto cleanup; 227 } 228 memset(&ifr, 0, sizeof(ifr)); 229 strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); 230 if (ioctl(rxfd, SIOCGIFINDEX, (void *) &ifr) < 0) { 231 err = -errno; 232 goto cleanup; 233 } 234 235 sock.sll_family = AF_PACKET; 236 sock.sll_protocol = htons(ETH_P_ALL); 237 sock.sll_ifindex = ifr.ifr_ifindex; 238 239 if (bind(rxfd, 240 (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { 241 err = -errno; 242 goto cleanup; 243 } 244 245 sock.sll_family = AF_PACKET; 246 sock.sll_protocol = htons(ETH_P_IP); 247 sock.sll_ifindex = ifr.ifr_ifindex; 248 249 if (bind(txfd, 250 (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { 251 err = -errno; 252 goto cleanup; 253 } 254 255 result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); 256 if (result != NULL) { 257 result->rx_fd = rxfd; 258 result->tx_fd = txfd; 259 result->remote_addr = NULL; 260 result->remote_addr_size = 0; 261 } 262 return result; 263 cleanup: 264 printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err); 265 if (rxfd >= 0) 266 os_close_file(rxfd); 267 if (txfd >= 0) 268 os_close_file(txfd); 269 kfree(result); 270 return NULL; 271 } 272 273 274 bool uml_raw_enable_qdisc_bypass(int fd) 275 { 276 int optval = 1; 277 278 if (setsockopt(fd, 279 SOL_PACKET, PACKET_QDISC_BYPASS, 280 &optval, sizeof(optval)) != 0) { 281 return false; 282 } 283 return true; 284 } 285 286 bool uml_raw_enable_vnet_headers(int fd) 287 { 288 int optval = 1; 289 290 if (setsockopt(fd, 291 SOL_PACKET, PACKET_VNET_HDR, 292 &optval, sizeof(optval)) != 0) { 293 printk(UM_KERN_INFO VNET_HDR_FAIL, fd); 294 return false; 295 } 296 return true; 297 } 298 bool uml_tap_enable_vnet_headers(int fd) 299 { 300 unsigned int features; 301 int len = sizeof(struct virtio_net_hdr); 302 303 if (ioctl(fd, TUNGETFEATURES, &features) == -1) { 304 printk(UM_KERN_INFO TUN_GET_F_FAIL, strerror(errno)); 305 return false; 306 } 307 if ((features & IFF_VNET_HDR) == 0) { 308 printk(UM_KERN_INFO "tapraw: No VNET HEADER support"); 309 return false; 310 } 311 ioctl(fd, TUNSETVNETHDRSZ, &len); 312 return true; 313 } 314 315 static struct vector_fds *user_init_socket_fds(struct arglist *ifspec, int id) 316 { 317 int err = -ENOMEM; 318 int fd = -1, gairet; 319 struct addrinfo srchints; 320 struct addrinfo dsthints; 321 bool v6, udp; 322 char *value; 323 char *src, *dst, *srcport, *dstport; 324 struct addrinfo *gairesult = NULL; 325 struct vector_fds *result = NULL; 326 327 328 value = uml_vector_fetch_arg(ifspec, "v6"); 329 v6 = false; 330 udp = false; 331 if (value != NULL) { 332 if (strtol((const char *) value, NULL, 10) > 0) 333 v6 = true; 334 } 335 336 value = uml_vector_fetch_arg(ifspec, "udp"); 337 if (value != NULL) { 338 if (strtol((const char *) value, NULL, 10) > 0) 339 udp = true; 340 } 341 src = uml_vector_fetch_arg(ifspec, "src"); 342 dst = uml_vector_fetch_arg(ifspec, "dst"); 343 srcport = uml_vector_fetch_arg(ifspec, "srcport"); 344 dstport = uml_vector_fetch_arg(ifspec, "dstport"); 345 346 memset(&dsthints, 0, sizeof(dsthints)); 347 348 if (v6) 349 dsthints.ai_family = AF_INET6; 350 else 351 dsthints.ai_family = AF_INET; 352 353 switch (id) { 354 case ID_GRE: 355 dsthints.ai_socktype = SOCK_RAW; 356 dsthints.ai_protocol = IPPROTO_GRE; 357 break; 358 case ID_L2TPV3: 359 if (udp) { 360 dsthints.ai_socktype = SOCK_DGRAM; 361 dsthints.ai_protocol = 0; 362 } else { 363 dsthints.ai_socktype = SOCK_RAW; 364 dsthints.ai_protocol = IPPROTO_L2TP; 365 } 366 break; 367 default: 368 printk(KERN_ERR "Unsupported socket type\n"); 369 return NULL; 370 } 371 memcpy(&srchints, &dsthints, sizeof(struct addrinfo)); 372 373 gairet = getaddrinfo(src, srcport, &dsthints, &gairesult); 374 if ((gairet != 0) || (gairesult == NULL)) { 375 printk(UM_KERN_ERR 376 "socket_open : could not resolve src, error = %s", 377 gai_strerror(gairet) 378 ); 379 return NULL; 380 } 381 fd = socket(gairesult->ai_family, 382 gairesult->ai_socktype, gairesult->ai_protocol); 383 if (fd == -1) { 384 printk(UM_KERN_ERR 385 "socket_open : could not open socket, error = %d", 386 -errno 387 ); 388 goto cleanup; 389 } 390 if (bind(fd, 391 (struct sockaddr *) gairesult->ai_addr, 392 gairesult->ai_addrlen)) { 393 printk(UM_KERN_ERR L2TPV3_BIND_FAIL, errno); 394 goto cleanup; 395 } 396 397 if (gairesult != NULL) 398 freeaddrinfo(gairesult); 399 400 gairesult = NULL; 401 402 gairet = getaddrinfo(dst, dstport, &dsthints, &gairesult); 403 if ((gairet != 0) || (gairesult == NULL)) { 404 printk(UM_KERN_ERR 405 "socket_open : could not resolve dst, error = %s", 406 gai_strerror(gairet) 407 ); 408 return NULL; 409 } 410 411 result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); 412 if (result != NULL) { 413 result->rx_fd = fd; 414 result->tx_fd = fd; 415 result->remote_addr = uml_kmalloc( 416 gairesult->ai_addrlen, UM_GFP_KERNEL); 417 if (result->remote_addr == NULL) 418 goto cleanup; 419 result->remote_addr_size = gairesult->ai_addrlen; 420 memcpy( 421 result->remote_addr, 422 gairesult->ai_addr, 423 gairesult->ai_addrlen 424 ); 425 } 426 freeaddrinfo(gairesult); 427 return result; 428 cleanup: 429 if (gairesult != NULL) 430 freeaddrinfo(gairesult); 431 printk(UM_KERN_ERR "user_init_socket: init failed, error %d", err); 432 if (fd >= 0) 433 os_close_file(fd); 434 if (result != NULL) { 435 kfree(result->remote_addr); 436 kfree(result); 437 } 438 return NULL; 439 } 440 441 struct vector_fds *uml_vector_user_open( 442 int unit, 443 struct arglist *parsed 444 ) 445 { 446 char *transport; 447 448 if (parsed == NULL) { 449 printk(UM_KERN_ERR "no parsed config for unit %d\n", unit); 450 return NULL; 451 } 452 transport = uml_vector_fetch_arg(parsed, "transport"); 453 if (transport == NULL) { 454 printk(UM_KERN_ERR "missing transport for unit %d\n", unit); 455 return NULL; 456 } 457 if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0) 458 return user_init_raw_fds(parsed); 459 if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0) 460 return user_init_tap_fds(parsed); 461 if (strncmp(transport, TRANS_GRE, TRANS_GRE_LEN) == 0) 462 return user_init_socket_fds(parsed, ID_GRE); 463 if (strncmp(transport, TRANS_L2TPV3, TRANS_L2TPV3_LEN) == 0) 464 return user_init_socket_fds(parsed, ID_L2TPV3); 465 return NULL; 466 } 467 468 469 int uml_vector_sendmsg(int fd, void *hdr, int flags) 470 { 471 int n; 472 473 CATCH_EINTR(n = sendmsg(fd, (struct msghdr *) hdr, flags)); 474 if ((n < 0) && (errno == EAGAIN)) 475 return 0; 476 if (n >= 0) 477 return n; 478 else 479 return -errno; 480 } 481 482 int uml_vector_recvmsg(int fd, void *hdr, int flags) 483 { 484 int n; 485 486 CATCH_EINTR(n = recvmsg(fd, (struct msghdr *) hdr, flags)); 487 if ((n < 0) && (errno == EAGAIN)) 488 return 0; 489 if (n >= 0) 490 return n; 491 else 492 return -errno; 493 } 494 495 int uml_vector_writev(int fd, void *hdr, int iovcount) 496 { 497 int n; 498 499 CATCH_EINTR(n = writev(fd, (struct iovec *) hdr, iovcount)); 500 if ((n < 0) && (errno == EAGAIN)) 501 return 0; 502 if (n >= 0) 503 return n; 504 else 505 return -errno; 506 } 507 508 int uml_vector_sendmmsg( 509 int fd, 510 void *msgvec, 511 unsigned int vlen, 512 unsigned int flags) 513 { 514 int n; 515 516 CATCH_EINTR(n = sendmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags)); 517 if ((n < 0) && (errno == EAGAIN)) 518 return 0; 519 if (n >= 0) 520 return n; 521 else 522 return -errno; 523 } 524 525 int uml_vector_recvmmsg( 526 int fd, 527 void *msgvec, 528 unsigned int vlen, 529 unsigned int flags) 530 { 531 int n; 532 533 CATCH_EINTR( 534 n = recvmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags, 0)); 535 if ((n < 0) && (errno == EAGAIN)) 536 return 0; 537 if (n >= 0) 538 return n; 539 else 540 return -errno; 541 } 542 int uml_vector_attach_bpf(int fd, void *bpf, int bpf_len) 543 { 544 int err = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, bpf, bpf_len); 545 546 if (err < 0) 547 printk(KERN_ERR BPF_ATTACH_FAIL, bpf_len, fd, -errno); 548 return err; 549 } 550 551 #define DEFAULT_BPF_LEN 6 552 553 void *uml_vector_default_bpf(int fd, void *mac) 554 { 555 struct sock_filter *bpf; 556 uint32_t *mac1 = (uint32_t *)(mac + 2); 557 uint16_t *mac2 = (uint16_t *) mac; 558 struct sock_fprog bpf_prog = { 559 .len = 6, 560 .filter = NULL, 561 }; 562 563 bpf = uml_kmalloc( 564 sizeof(struct sock_filter) * DEFAULT_BPF_LEN, UM_GFP_KERNEL); 565 if (bpf != NULL) { 566 bpf_prog.filter = bpf; 567 /* ld [8] */ 568 bpf[0] = (struct sock_filter){ 0x20, 0, 0, 0x00000008 }; 569 /* jeq #0xMAC[2-6] jt 2 jf 5*/ 570 bpf[1] = (struct sock_filter){ 0x15, 0, 3, ntohl(*mac1)}; 571 /* ldh [6] */ 572 bpf[2] = (struct sock_filter){ 0x28, 0, 0, 0x00000006 }; 573 /* jeq #0xMAC[0-1] jt 4 jf 5 */ 574 bpf[3] = (struct sock_filter){ 0x15, 0, 1, ntohs(*mac2)}; 575 /* ret #0 */ 576 bpf[4] = (struct sock_filter){ 0x6, 0, 0, 0x00000000 }; 577 /* ret #0x40000 */ 578 bpf[5] = (struct sock_filter){ 0x6, 0, 0, 0x00040000 }; 579 if (uml_vector_attach_bpf( 580 fd, &bpf_prog, sizeof(struct sock_fprog)) < 0) { 581 kfree(bpf); 582 bpf = NULL; 583 } 584 } 585 return bpf; 586 } 587 588