1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 4 */ 5 6 #include <stdbool.h> 7 #include <stdio.h> 8 #include <unistd.h> 9 #include <stdarg.h> 10 #include <errno.h> 11 #include <stddef.h> 12 #include <string.h> 13 #include <sys/ioctl.h> 14 #include <net/if.h> 15 #include <linux/if_tun.h> 16 #include <arpa/inet.h> 17 #include <sys/types.h> 18 #include <sys/stat.h> 19 #include <fcntl.h> 20 #include <sys/socket.h> 21 #include <sys/un.h> 22 #include <netinet/ip.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 <limits.h> 32 #include <um_malloc.h> 33 #include "vector_user.h" 34 35 #define ID_GRE 0 36 #define ID_L2TPV3 1 37 #define ID_BESS 2 38 #define ID_MAX 2 39 40 #define TOKEN_IFNAME "ifname" 41 #define TOKEN_SCRIPT "ifup" 42 43 #define TRANS_RAW "raw" 44 #define TRANS_RAW_LEN strlen(TRANS_RAW) 45 46 #define TRANS_FD "fd" 47 #define TRANS_FD_LEN strlen(TRANS_FD) 48 49 #define TRANS_VDE "vde" 50 #define TRANS_VDE_LEN strlen(TRANS_VDE) 51 52 #define VNET_HDR_FAIL "could not enable vnet headers on fd %d" 53 #define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s" 54 #define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i" 55 #define UNIX_BIND_FAIL "unix_open : could not bind socket err=%i" 56 #define BPF_ATTACH_FAIL "Failed to attach filter size %d prog %px to %d, err %d\n" 57 #define BPF_DETACH_FAIL "Failed to detach filter size %d prog %px to %d, err %d\n" 58 59 #define MAX_UN_LEN 107 60 61 static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 62 static const char *template = "tapXXXXXX"; 63 64 /* This is very ugly and brute force lookup, but it is done 65 * only once at initialization so not worth doing hashes or 66 * anything more intelligent 67 */ 68 69 char *uml_vector_fetch_arg(struct arglist *ifspec, char *token) 70 { 71 int i; 72 73 for (i = 0; i < ifspec->numargs; i++) { 74 if (strcmp(ifspec->tokens[i], token) == 0) 75 return ifspec->values[i]; 76 } 77 return NULL; 78 79 } 80 81 struct arglist *uml_parse_vector_ifspec(char *arg) 82 { 83 struct arglist *result; 84 int pos, len; 85 bool parsing_token = true, next_starts = true; 86 87 if (arg == NULL) 88 return NULL; 89 result = uml_kmalloc(sizeof(struct arglist), UM_GFP_KERNEL); 90 if (result == NULL) 91 return NULL; 92 result->numargs = 0; 93 len = strlen(arg); 94 for (pos = 0; pos < len; pos++) { 95 if (next_starts) { 96 if (result->numargs >= MAXVARGS) 97 goto cleanup; 98 99 if (parsing_token) { 100 result->tokens[result->numargs] = arg + pos; 101 } else { 102 result->values[result->numargs] = arg + pos; 103 result->numargs++; 104 } 105 next_starts = false; 106 } 107 if (*(arg + pos) == '=') { 108 if (parsing_token) 109 parsing_token = false; 110 else 111 goto cleanup; 112 next_starts = true; 113 (*(arg + pos)) = '\0'; 114 } 115 if (*(arg + pos) == ',') { 116 parsing_token = true; 117 next_starts = true; 118 (*(arg + pos)) = '\0'; 119 } 120 } 121 return result; 122 cleanup: 123 printk(UM_KERN_ERR "vector_setup - Couldn't parse '%s'\n", arg); 124 kfree(result); 125 return NULL; 126 } 127 128 /* 129 * Socket/FD configuration functions. These return an structure 130 * of rx and tx descriptors to cover cases where these are not 131 * the same (f.e. read via raw socket and write via tap). 132 */ 133 134 #define PATH_NET_TUN "/dev/net/tun" 135 136 137 static int create_tap_fd(char *iface) 138 { 139 struct ifreq ifr; 140 int fd = -1; 141 int err = -ENOMEM, offload; 142 143 fd = open(PATH_NET_TUN, O_RDWR); 144 if (fd < 0) { 145 printk(UM_KERN_ERR "uml_tap: failed to open tun device\n"); 146 goto tap_fd_cleanup; 147 } 148 memset(&ifr, 0, sizeof(ifr)); 149 ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR; 150 strscpy(ifr.ifr_name, iface); 151 152 err = ioctl(fd, TUNSETIFF, (void *) &ifr); 153 if (err != 0) { 154 printk(UM_KERN_ERR "uml_tap: failed to select tap interface\n"); 155 goto tap_fd_cleanup; 156 } 157 158 offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6; 159 ioctl(fd, TUNSETOFFLOAD, offload); 160 return fd; 161 tap_fd_cleanup: 162 if (fd >= 0) 163 os_close_file(fd); 164 return err; 165 } 166 167 static int create_raw_fd(char *iface, int flags, int proto) 168 { 169 struct ifreq ifr; 170 int fd = -1; 171 struct sockaddr_ll sock; 172 int err = -ENOMEM; 173 174 fd = socket(AF_PACKET, SOCK_RAW, flags); 175 if (fd == -1) { 176 err = -errno; 177 goto raw_fd_cleanup; 178 } 179 memset(&ifr, 0, sizeof(ifr)); 180 strscpy(ifr.ifr_name, iface); 181 if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) { 182 err = -errno; 183 goto raw_fd_cleanup; 184 } 185 186 sock.sll_family = AF_PACKET; 187 sock.sll_protocol = htons(proto); 188 sock.sll_ifindex = ifr.ifr_ifindex; 189 190 if (bind(fd, 191 (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { 192 err = -errno; 193 goto raw_fd_cleanup; 194 } 195 return fd; 196 raw_fd_cleanup: 197 printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err); 198 if (fd >= 0) 199 os_close_file(fd); 200 return err; 201 } 202 203 204 static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) 205 { 206 int fd = -1, i; 207 char *iface; 208 struct vector_fds *result = NULL; 209 bool dynamic = false; 210 char dynamic_ifname[IFNAMSIZ]; 211 char *argv[] = {NULL, NULL, NULL, NULL}; 212 213 iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); 214 if (iface == NULL) { 215 dynamic = true; 216 iface = dynamic_ifname; 217 srand(getpid()); 218 } 219 220 result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); 221 if (result == NULL) { 222 printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n"); 223 goto tap_cleanup; 224 } 225 result->rx_fd = -1; 226 result->tx_fd = -1; 227 result->remote_addr = NULL; 228 result->remote_addr_size = 0; 229 230 /* TAP */ 231 do { 232 if (dynamic) { 233 strcpy(iface, template); 234 for (i = 0; i < strlen(iface); i++) { 235 if (iface[i] == 'X') { 236 iface[i] = padchar[rand() % strlen(padchar)]; 237 } 238 } 239 } 240 fd = create_tap_fd(iface); 241 if ((fd < 0) && (!dynamic)) { 242 printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n"); 243 goto tap_cleanup; 244 } 245 result->tx_fd = fd; 246 result->rx_fd = fd; 247 } while (fd < 0); 248 249 argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT); 250 if (argv[0]) { 251 argv[1] = iface; 252 run_helper(NULL, NULL, argv); 253 } 254 255 return result; 256 tap_cleanup: 257 printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd); 258 kfree(result); 259 return NULL; 260 } 261 262 static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec) 263 { 264 char *iface; 265 struct vector_fds *result = NULL; 266 char *argv[] = {NULL, NULL, NULL, NULL}; 267 268 iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); 269 if (iface == NULL) { 270 printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n"); 271 goto hybrid_cleanup; 272 } 273 274 result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); 275 if (result == NULL) { 276 printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n"); 277 goto hybrid_cleanup; 278 } 279 result->rx_fd = -1; 280 result->tx_fd = -1; 281 result->remote_addr = NULL; 282 result->remote_addr_size = 0; 283 284 /* TAP */ 285 286 result->tx_fd = create_tap_fd(iface); 287 if (result->tx_fd < 0) { 288 printk(UM_KERN_ERR "uml_tap: failed to create tun interface: %i\n", result->tx_fd); 289 goto hybrid_cleanup; 290 } 291 292 /* RAW */ 293 294 result->rx_fd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL); 295 if (result->rx_fd == -1) { 296 printk(UM_KERN_ERR 297 "uml_tap: failed to create paired raw socket: %i\n", result->rx_fd); 298 goto hybrid_cleanup; 299 } 300 301 argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT); 302 if (argv[0]) { 303 argv[1] = iface; 304 run_helper(NULL, NULL, argv); 305 } 306 return result; 307 hybrid_cleanup: 308 printk(UM_KERN_ERR "user_init_hybrid: init failed"); 309 kfree(result); 310 return NULL; 311 } 312 313 static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id) 314 { 315 int fd = -1; 316 int socktype; 317 char *src, *dst; 318 struct vector_fds *result = NULL; 319 struct sockaddr_un *local_addr = NULL, *remote_addr = NULL; 320 321 src = uml_vector_fetch_arg(ifspec, "src"); 322 dst = uml_vector_fetch_arg(ifspec, "dst"); 323 result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); 324 if (result == NULL) { 325 printk(UM_KERN_ERR "unix open:cannot allocate remote addr"); 326 goto unix_cleanup; 327 } 328 remote_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); 329 if (remote_addr == NULL) { 330 printk(UM_KERN_ERR "unix open:cannot allocate remote addr"); 331 goto unix_cleanup; 332 } 333 334 switch (id) { 335 case ID_BESS: 336 socktype = SOCK_SEQPACKET; 337 if ((src != NULL) && (strlen(src) <= MAX_UN_LEN)) { 338 local_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); 339 if (local_addr == NULL) { 340 printk(UM_KERN_ERR "bess open:cannot allocate local addr"); 341 goto unix_cleanup; 342 } 343 local_addr->sun_family = AF_UNIX; 344 memcpy(local_addr->sun_path, src, strlen(src) + 1); 345 } 346 if ((dst == NULL) || (strlen(dst) > MAX_UN_LEN)) 347 goto unix_cleanup; 348 remote_addr->sun_family = AF_UNIX; 349 memcpy(remote_addr->sun_path, dst, strlen(dst) + 1); 350 break; 351 default: 352 printk(KERN_ERR "Unsupported unix socket type\n"); 353 return NULL; 354 } 355 356 fd = socket(AF_UNIX, socktype, 0); 357 if (fd == -1) { 358 printk(UM_KERN_ERR 359 "unix open: could not open socket, error = %d", 360 -errno 361 ); 362 goto unix_cleanup; 363 } 364 if (local_addr != NULL) { 365 if (bind(fd, (struct sockaddr *) local_addr, sizeof(struct sockaddr_un))) { 366 printk(UM_KERN_ERR UNIX_BIND_FAIL, errno); 367 goto unix_cleanup; 368 } 369 } 370 switch (id) { 371 case ID_BESS: 372 if (connect(fd, (const struct sockaddr *) remote_addr, sizeof(struct sockaddr_un)) < 0) { 373 printk(UM_KERN_ERR "bess open:cannot connect to %s %i", remote_addr->sun_path, -errno); 374 goto unix_cleanup; 375 } 376 break; 377 } 378 result->rx_fd = fd; 379 result->tx_fd = fd; 380 result->remote_addr_size = sizeof(struct sockaddr_un); 381 result->remote_addr = remote_addr; 382 return result; 383 unix_cleanup: 384 if (fd >= 0) 385 os_close_file(fd); 386 kfree(remote_addr); 387 kfree(result); 388 return NULL; 389 } 390 391 static int strtofd(const char *nptr) 392 { 393 long fd; 394 char *endptr; 395 396 if (nptr == NULL) 397 return -1; 398 399 errno = 0; 400 fd = strtol(nptr, &endptr, 10); 401 if (nptr == endptr || 402 errno != 0 || 403 *endptr != '\0' || 404 fd < 0 || 405 fd > INT_MAX) { 406 return -1; 407 } 408 return fd; 409 } 410 411 static struct vector_fds *user_init_fd_fds(struct arglist *ifspec) 412 { 413 int fd = -1; 414 char *fdarg = NULL; 415 struct vector_fds *result = NULL; 416 417 fdarg = uml_vector_fetch_arg(ifspec, "fd"); 418 fd = strtofd(fdarg); 419 if (fd == -1) { 420 printk(UM_KERN_ERR "fd open: bad or missing fd argument"); 421 goto fd_cleanup; 422 } 423 424 result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); 425 if (result == NULL) { 426 printk(UM_KERN_ERR "fd open: allocation failed"); 427 goto fd_cleanup; 428 } 429 430 result->rx_fd = fd; 431 result->tx_fd = fd; 432 result->remote_addr_size = 0; 433 result->remote_addr = NULL; 434 return result; 435 436 fd_cleanup: 437 if (fd >= 0) 438 os_close_file(fd); 439 kfree(result); 440 return NULL; 441 } 442 443 /* enough char to store an int type */ 444 #define ENOUGH(type) ((CHAR_BIT * sizeof(type) - 1) / 3 + 2) 445 #define ENOUGH_OCTAL(type) ((CHAR_BIT * sizeof(type) + 2) / 3) 446 /* vde_plug --descr xx --port2 xx --mod2 xx --group2 xx seqpacket://NN vnl (NULL) */ 447 #define VDE_MAX_ARGC 12 448 #define VDE_SEQPACKET_HEAD "seqpacket://" 449 #define VDE_SEQPACKET_HEAD_LEN (sizeof(VDE_SEQPACKET_HEAD) - 1) 450 #define VDE_DEFAULT_DESCRIPTION "UML" 451 452 static struct vector_fds *user_init_vde_fds(struct arglist *ifspec) 453 { 454 char seqpacketvnl[VDE_SEQPACKET_HEAD_LEN + ENOUGH(int) + 1]; 455 char *argv[VDE_MAX_ARGC] = {"vde_plug"}; 456 int argc = 1; 457 int rv; 458 int sv[2]; 459 struct vector_fds *result = NULL; 460 461 char *vnl = uml_vector_fetch_arg(ifspec,"vnl"); 462 char *descr = uml_vector_fetch_arg(ifspec,"descr"); 463 char *port = uml_vector_fetch_arg(ifspec,"port"); 464 char *mode = uml_vector_fetch_arg(ifspec,"mode"); 465 char *group = uml_vector_fetch_arg(ifspec,"group"); 466 if (descr == NULL) descr = VDE_DEFAULT_DESCRIPTION; 467 468 argv[argc++] = "--descr"; 469 argv[argc++] = descr; 470 if (port != NULL) { 471 argv[argc++] = "--port2"; 472 argv[argc++] = port; 473 } 474 if (mode != NULL) { 475 argv[argc++] = "--mod2"; 476 argv[argc++] = mode; 477 } 478 if (group != NULL) { 479 argv[argc++] = "--group2"; 480 argv[argc++] = group; 481 } 482 argv[argc++] = seqpacketvnl; 483 argv[argc++] = vnl; 484 argv[argc++] = NULL; 485 486 rv = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sv); 487 if (rv < 0) { 488 printk(UM_KERN_ERR "vde: seqpacket socketpair err %d", -errno); 489 return NULL; 490 } 491 rv = os_set_exec_close(sv[0]); 492 if (rv < 0) { 493 printk(UM_KERN_ERR "vde: seqpacket socketpair cloexec err %d", -errno); 494 goto vde_cleanup_sv; 495 } 496 snprintf(seqpacketvnl, sizeof(seqpacketvnl), VDE_SEQPACKET_HEAD "%d", sv[1]); 497 498 run_helper(NULL, NULL, argv); 499 500 close(sv[1]); 501 502 result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); 503 if (result == NULL) { 504 printk(UM_KERN_ERR "fd open: allocation failed"); 505 goto vde_cleanup; 506 } 507 508 result->rx_fd = sv[0]; 509 result->tx_fd = sv[0]; 510 result->remote_addr_size = 0; 511 result->remote_addr = NULL; 512 return result; 513 514 vde_cleanup_sv: 515 close(sv[1]); 516 vde_cleanup: 517 close(sv[0]); 518 return NULL; 519 } 520 521 static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) 522 { 523 int rxfd = -1, txfd = -1; 524 int err = -ENOMEM; 525 char *iface; 526 struct vector_fds *result = NULL; 527 char *argv[] = {NULL, NULL, NULL, NULL}; 528 529 iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); 530 if (iface == NULL) 531 goto raw_cleanup; 532 533 rxfd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL); 534 if (rxfd == -1) { 535 err = -errno; 536 goto raw_cleanup; 537 } 538 txfd = create_raw_fd(iface, 0, ETH_P_IP); /* Turn off RX on this fd */ 539 if (txfd == -1) { 540 err = -errno; 541 goto raw_cleanup; 542 } 543 result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); 544 if (result != NULL) { 545 result->rx_fd = rxfd; 546 result->tx_fd = txfd; 547 result->remote_addr = NULL; 548 result->remote_addr_size = 0; 549 } 550 argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT); 551 if (argv[0]) { 552 argv[1] = iface; 553 run_helper(NULL, NULL, argv); 554 } 555 return result; 556 raw_cleanup: 557 printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err); 558 kfree(result); 559 return NULL; 560 } 561 562 563 bool uml_raw_enable_qdisc_bypass(int fd) 564 { 565 int optval = 1; 566 567 if (setsockopt(fd, 568 SOL_PACKET, PACKET_QDISC_BYPASS, 569 &optval, sizeof(optval)) != 0) { 570 return false; 571 } 572 return true; 573 } 574 575 bool uml_raw_enable_vnet_headers(int fd) 576 { 577 int optval = 1; 578 579 if (setsockopt(fd, 580 SOL_PACKET, PACKET_VNET_HDR, 581 &optval, sizeof(optval)) != 0) { 582 printk(UM_KERN_INFO VNET_HDR_FAIL, fd); 583 return false; 584 } 585 return true; 586 } 587 bool uml_tap_enable_vnet_headers(int fd) 588 { 589 unsigned int features; 590 int len = sizeof(struct virtio_net_hdr); 591 592 if (ioctl(fd, TUNGETFEATURES, &features) == -1) { 593 printk(UM_KERN_INFO TUN_GET_F_FAIL, strerror(errno)); 594 return false; 595 } 596 if ((features & IFF_VNET_HDR) == 0) { 597 printk(UM_KERN_INFO "tapraw: No VNET HEADER support"); 598 return false; 599 } 600 ioctl(fd, TUNSETVNETHDRSZ, &len); 601 return true; 602 } 603 604 static struct vector_fds *user_init_socket_fds(struct arglist *ifspec, int id) 605 { 606 int err = -ENOMEM; 607 int fd = -1, gairet; 608 struct addrinfo srchints; 609 struct addrinfo dsthints; 610 bool v6, udp; 611 char *value; 612 char *src, *dst, *srcport, *dstport; 613 struct addrinfo *gairesult = NULL; 614 struct vector_fds *result = NULL; 615 616 617 value = uml_vector_fetch_arg(ifspec, "v6"); 618 v6 = false; 619 udp = false; 620 if (value != NULL) { 621 if (strtol((const char *) value, NULL, 10) > 0) 622 v6 = true; 623 } 624 625 value = uml_vector_fetch_arg(ifspec, "udp"); 626 if (value != NULL) { 627 if (strtol((const char *) value, NULL, 10) > 0) 628 udp = true; 629 } 630 src = uml_vector_fetch_arg(ifspec, "src"); 631 dst = uml_vector_fetch_arg(ifspec, "dst"); 632 srcport = uml_vector_fetch_arg(ifspec, "srcport"); 633 dstport = uml_vector_fetch_arg(ifspec, "dstport"); 634 635 memset(&dsthints, 0, sizeof(dsthints)); 636 637 if (v6) 638 dsthints.ai_family = AF_INET6; 639 else 640 dsthints.ai_family = AF_INET; 641 642 switch (id) { 643 case ID_GRE: 644 dsthints.ai_socktype = SOCK_RAW; 645 dsthints.ai_protocol = IPPROTO_GRE; 646 break; 647 case ID_L2TPV3: 648 if (udp) { 649 dsthints.ai_socktype = SOCK_DGRAM; 650 dsthints.ai_protocol = 0; 651 } else { 652 dsthints.ai_socktype = SOCK_RAW; 653 dsthints.ai_protocol = IPPROTO_L2TP; 654 } 655 break; 656 default: 657 printk(KERN_ERR "Unsupported socket type\n"); 658 return NULL; 659 } 660 memcpy(&srchints, &dsthints, sizeof(struct addrinfo)); 661 662 gairet = getaddrinfo(src, srcport, &dsthints, &gairesult); 663 if ((gairet != 0) || (gairesult == NULL)) { 664 printk(UM_KERN_ERR 665 "socket_open : could not resolve src, error = %s", 666 gai_strerror(gairet) 667 ); 668 return NULL; 669 } 670 fd = socket(gairesult->ai_family, 671 gairesult->ai_socktype, gairesult->ai_protocol); 672 if (fd == -1) { 673 printk(UM_KERN_ERR 674 "socket_open : could not open socket, error = %d", 675 -errno 676 ); 677 goto cleanup; 678 } 679 if (bind(fd, 680 (struct sockaddr *) gairesult->ai_addr, 681 gairesult->ai_addrlen)) { 682 printk(UM_KERN_ERR L2TPV3_BIND_FAIL, errno); 683 goto cleanup; 684 } 685 686 if (gairesult != NULL) 687 freeaddrinfo(gairesult); 688 689 gairesult = NULL; 690 691 gairet = getaddrinfo(dst, dstport, &dsthints, &gairesult); 692 if ((gairet != 0) || (gairesult == NULL)) { 693 printk(UM_KERN_ERR 694 "socket_open : could not resolve dst, error = %s", 695 gai_strerror(gairet) 696 ); 697 return NULL; 698 } 699 700 result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); 701 if (result != NULL) { 702 result->rx_fd = fd; 703 result->tx_fd = fd; 704 result->remote_addr = uml_kmalloc( 705 gairesult->ai_addrlen, UM_GFP_KERNEL); 706 if (result->remote_addr == NULL) 707 goto cleanup; 708 result->remote_addr_size = gairesult->ai_addrlen; 709 memcpy( 710 result->remote_addr, 711 gairesult->ai_addr, 712 gairesult->ai_addrlen 713 ); 714 } 715 freeaddrinfo(gairesult); 716 return result; 717 cleanup: 718 if (gairesult != NULL) 719 freeaddrinfo(gairesult); 720 printk(UM_KERN_ERR "user_init_socket: init failed, error %d", err); 721 if (fd >= 0) 722 os_close_file(fd); 723 if (result != NULL) { 724 kfree(result->remote_addr); 725 kfree(result); 726 } 727 return NULL; 728 } 729 730 struct vector_fds *uml_vector_user_open( 731 int unit, 732 struct arglist *parsed 733 ) 734 { 735 char *transport; 736 737 if (parsed == NULL) { 738 printk(UM_KERN_ERR "no parsed config for unit %d\n", unit); 739 return NULL; 740 } 741 transport = uml_vector_fetch_arg(parsed, "transport"); 742 if (transport == NULL) { 743 printk(UM_KERN_ERR "missing transport for unit %d\n", unit); 744 return NULL; 745 } 746 if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0) 747 return user_init_raw_fds(parsed); 748 if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0) 749 return user_init_hybrid_fds(parsed); 750 if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0) 751 return user_init_tap_fds(parsed); 752 if (strncmp(transport, TRANS_GRE, TRANS_GRE_LEN) == 0) 753 return user_init_socket_fds(parsed, ID_GRE); 754 if (strncmp(transport, TRANS_L2TPV3, TRANS_L2TPV3_LEN) == 0) 755 return user_init_socket_fds(parsed, ID_L2TPV3); 756 if (strncmp(transport, TRANS_BESS, TRANS_BESS_LEN) == 0) 757 return user_init_unix_fds(parsed, ID_BESS); 758 if (strncmp(transport, TRANS_FD, TRANS_FD_LEN) == 0) 759 return user_init_fd_fds(parsed); 760 if (strncmp(transport, TRANS_VDE, TRANS_VDE_LEN) == 0) 761 return user_init_vde_fds(parsed); 762 return NULL; 763 } 764 765 766 int uml_vector_sendmsg(int fd, void *hdr, int flags) 767 { 768 int n; 769 770 CATCH_EINTR(n = sendmsg(fd, (struct msghdr *) hdr, flags)); 771 if ((n < 0) && (errno == EAGAIN)) 772 return 0; 773 if (n >= 0) 774 return n; 775 else 776 return -errno; 777 } 778 779 int uml_vector_recvmsg(int fd, void *hdr, int flags) 780 { 781 int n; 782 struct msghdr *msg = (struct msghdr *) hdr; 783 784 CATCH_EINTR(n = readv(fd, msg->msg_iov, msg->msg_iovlen)); 785 if ((n < 0) && (errno == EAGAIN)) 786 return 0; 787 if (n >= 0) 788 return n; 789 else 790 return -errno; 791 } 792 793 int uml_vector_writev(int fd, void *hdr, int iovcount) 794 { 795 int n; 796 797 CATCH_EINTR(n = writev(fd, (struct iovec *) hdr, iovcount)); 798 if ((n < 0) && ((errno == EAGAIN) || (errno == ENOBUFS))) 799 return 0; 800 if (n >= 0) 801 return n; 802 else 803 return -errno; 804 } 805 806 int uml_vector_sendmmsg( 807 int fd, 808 void *msgvec, 809 unsigned int vlen, 810 unsigned int flags) 811 { 812 int n; 813 814 CATCH_EINTR(n = sendmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags)); 815 if ((n < 0) && ((errno == EAGAIN) || (errno == ENOBUFS))) 816 return 0; 817 if (n >= 0) 818 return n; 819 else 820 return -errno; 821 } 822 823 int uml_vector_recvmmsg( 824 int fd, 825 void *msgvec, 826 unsigned int vlen, 827 unsigned int flags) 828 { 829 int n; 830 831 CATCH_EINTR( 832 n = recvmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags, 0)); 833 if ((n < 0) && (errno == EAGAIN)) 834 return 0; 835 if (n >= 0) 836 return n; 837 else 838 return -errno; 839 } 840 int uml_vector_attach_bpf(int fd, void *bpf) 841 { 842 struct sock_fprog *prog = bpf; 843 844 int err = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, bpf, sizeof(struct sock_fprog)); 845 846 if (err < 0) 847 printk(KERN_ERR BPF_ATTACH_FAIL, prog->len, prog->filter, fd, -errno); 848 return err; 849 } 850 851 int uml_vector_detach_bpf(int fd, void *bpf) 852 { 853 struct sock_fprog *prog = bpf; 854 855 int err = setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, bpf, sizeof(struct sock_fprog)); 856 if (err < 0) 857 printk(KERN_ERR BPF_DETACH_FAIL, prog->len, prog->filter, fd, -errno); 858 return err; 859 } 860 void *uml_vector_default_bpf(const void *mac) 861 { 862 struct sock_filter *bpf; 863 uint32_t *mac1 = (uint32_t *)(mac + 2); 864 uint16_t *mac2 = (uint16_t *) mac; 865 struct sock_fprog *bpf_prog; 866 867 bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL); 868 if (bpf_prog) { 869 bpf_prog->len = DEFAULT_BPF_LEN; 870 bpf_prog->filter = NULL; 871 } else { 872 return NULL; 873 } 874 bpf = uml_kmalloc( 875 sizeof(struct sock_filter) * DEFAULT_BPF_LEN, UM_GFP_KERNEL); 876 if (bpf) { 877 bpf_prog->filter = bpf; 878 /* ld [8] */ 879 bpf[0] = (struct sock_filter){ 0x20, 0, 0, 0x00000008 }; 880 /* jeq #0xMAC[2-6] jt 2 jf 5*/ 881 bpf[1] = (struct sock_filter){ 0x15, 0, 3, ntohl(*mac1)}; 882 /* ldh [6] */ 883 bpf[2] = (struct sock_filter){ 0x28, 0, 0, 0x00000006 }; 884 /* jeq #0xMAC[0-1] jt 4 jf 5 */ 885 bpf[3] = (struct sock_filter){ 0x15, 0, 1, ntohs(*mac2)}; 886 /* ret #0 */ 887 bpf[4] = (struct sock_filter){ 0x6, 0, 0, 0x00000000 }; 888 /* ret #0x40000 */ 889 bpf[5] = (struct sock_filter){ 0x6, 0, 0, 0x00040000 }; 890 } else { 891 kfree(bpf_prog); 892 bpf_prog = NULL; 893 } 894 return bpf_prog; 895 } 896 897 /* Note - this function requires a valid mac being passed as an arg */ 898 899 void *uml_vector_user_bpf(char *filename) 900 { 901 struct sock_filter *bpf; 902 struct sock_fprog *bpf_prog; 903 struct stat statbuf; 904 int res, ffd = -1; 905 906 if (filename == NULL) 907 return NULL; 908 909 if (stat(filename, &statbuf) < 0) { 910 printk(KERN_ERR "Error %d reading bpf file", -errno); 911 return false; 912 } 913 bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL); 914 if (bpf_prog == NULL) { 915 printk(KERN_ERR "Failed to allocate bpf prog buffer"); 916 return NULL; 917 } 918 bpf_prog->len = statbuf.st_size / sizeof(struct sock_filter); 919 bpf_prog->filter = NULL; 920 ffd = os_open_file(filename, of_read(OPENFLAGS()), 0); 921 if (ffd < 0) { 922 printk(KERN_ERR "Error %d opening bpf file", -errno); 923 goto bpf_failed; 924 } 925 bpf = uml_kmalloc(statbuf.st_size, UM_GFP_KERNEL); 926 if (bpf == NULL) { 927 printk(KERN_ERR "Failed to allocate bpf buffer"); 928 goto bpf_failed; 929 } 930 bpf_prog->filter = bpf; 931 res = os_read_file(ffd, bpf, statbuf.st_size); 932 if (res < statbuf.st_size) { 933 printk(KERN_ERR "Failed to read bpf program %s, error %d", filename, res); 934 kfree(bpf); 935 goto bpf_failed; 936 } 937 os_close_file(ffd); 938 return bpf_prog; 939 bpf_failed: 940 if (ffd > 0) 941 os_close_file(ffd); 942 kfree(bpf_prog); 943 return NULL; 944 } 945