1 /*- 2 * Copyright (c) 2015 Dmitry Chagin <dchagin@FreeBSD.org> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include <sys/cdefs.h> 27 __FBSDID("$FreeBSD$"); 28 29 #include "opt_inet6.h" 30 31 #include <sys/param.h> 32 #include <sys/conf.h> 33 #include <sys/ctype.h> 34 #include <sys/file.h> 35 #include <sys/filedesc.h> 36 #include <sys/jail.h> 37 #include <sys/lock.h> 38 #include <sys/malloc.h> 39 #include <sys/poll.h> 40 #include <sys/proc.h> 41 #include <sys/signalvar.h> 42 #include <sys/socket.h> 43 #include <sys/socketvar.h> 44 45 #include <net/if.h> 46 #include <net/if_var.h> 47 #include <net/if_dl.h> 48 #include <net/if_types.h> 49 #include <netlink/netlink.h> 50 51 #include <sys/un.h> 52 #include <netinet/in.h> 53 54 #include <compat/linux/linux.h> 55 #include <compat/linux/linux_common.h> 56 #include <compat/linux/linux_mib.h> 57 #include <compat/linux/linux_util.h> 58 59 CTASSERT(LINUX_IFNAMSIZ == IFNAMSIZ); 60 61 static bool use_real_ifnames = false; 62 SYSCTL_BOOL(_compat_linux, OID_AUTO, use_real_ifnames, CTLFLAG_RWTUN, 63 &use_real_ifnames, 0, 64 "Use FreeBSD interface names instead of generating ethN aliases"); 65 66 static int bsd_to_linux_sigtbl[LINUX_SIGTBLSZ] = { 67 LINUX_SIGHUP, /* SIGHUP */ 68 LINUX_SIGINT, /* SIGINT */ 69 LINUX_SIGQUIT, /* SIGQUIT */ 70 LINUX_SIGILL, /* SIGILL */ 71 LINUX_SIGTRAP, /* SIGTRAP */ 72 LINUX_SIGABRT, /* SIGABRT */ 73 0, /* SIGEMT */ 74 LINUX_SIGFPE, /* SIGFPE */ 75 LINUX_SIGKILL, /* SIGKILL */ 76 LINUX_SIGBUS, /* SIGBUS */ 77 LINUX_SIGSEGV, /* SIGSEGV */ 78 LINUX_SIGSYS, /* SIGSYS */ 79 LINUX_SIGPIPE, /* SIGPIPE */ 80 LINUX_SIGALRM, /* SIGALRM */ 81 LINUX_SIGTERM, /* SIGTERM */ 82 LINUX_SIGURG, /* SIGURG */ 83 LINUX_SIGSTOP, /* SIGSTOP */ 84 LINUX_SIGTSTP, /* SIGTSTP */ 85 LINUX_SIGCONT, /* SIGCONT */ 86 LINUX_SIGCHLD, /* SIGCHLD */ 87 LINUX_SIGTTIN, /* SIGTTIN */ 88 LINUX_SIGTTOU, /* SIGTTOU */ 89 LINUX_SIGIO, /* SIGIO */ 90 LINUX_SIGXCPU, /* SIGXCPU */ 91 LINUX_SIGXFSZ, /* SIGXFSZ */ 92 LINUX_SIGVTALRM,/* SIGVTALRM */ 93 LINUX_SIGPROF, /* SIGPROF */ 94 LINUX_SIGWINCH, /* SIGWINCH */ 95 0, /* SIGINFO */ 96 LINUX_SIGUSR1, /* SIGUSR1 */ 97 LINUX_SIGUSR2 /* SIGUSR2 */ 98 }; 99 100 #define LINUX_SIGPWREMU (SIGRTMIN + (LINUX_SIGRTMAX - LINUX_SIGRTMIN) + 1) 101 102 static int linux_to_bsd_sigtbl[LINUX_SIGTBLSZ] = { 103 SIGHUP, /* LINUX_SIGHUP */ 104 SIGINT, /* LINUX_SIGINT */ 105 SIGQUIT, /* LINUX_SIGQUIT */ 106 SIGILL, /* LINUX_SIGILL */ 107 SIGTRAP, /* LINUX_SIGTRAP */ 108 SIGABRT, /* LINUX_SIGABRT */ 109 SIGBUS, /* LINUX_SIGBUS */ 110 SIGFPE, /* LINUX_SIGFPE */ 111 SIGKILL, /* LINUX_SIGKILL */ 112 SIGUSR1, /* LINUX_SIGUSR1 */ 113 SIGSEGV, /* LINUX_SIGSEGV */ 114 SIGUSR2, /* LINUX_SIGUSR2 */ 115 SIGPIPE, /* LINUX_SIGPIPE */ 116 SIGALRM, /* LINUX_SIGALRM */ 117 SIGTERM, /* LINUX_SIGTERM */ 118 SIGBUS, /* LINUX_SIGSTKFLT */ 119 SIGCHLD, /* LINUX_SIGCHLD */ 120 SIGCONT, /* LINUX_SIGCONT */ 121 SIGSTOP, /* LINUX_SIGSTOP */ 122 SIGTSTP, /* LINUX_SIGTSTP */ 123 SIGTTIN, /* LINUX_SIGTTIN */ 124 SIGTTOU, /* LINUX_SIGTTOU */ 125 SIGURG, /* LINUX_SIGURG */ 126 SIGXCPU, /* LINUX_SIGXCPU */ 127 SIGXFSZ, /* LINUX_SIGXFSZ */ 128 SIGVTALRM, /* LINUX_SIGVTALARM */ 129 SIGPROF, /* LINUX_SIGPROF */ 130 SIGWINCH, /* LINUX_SIGWINCH */ 131 SIGIO, /* LINUX_SIGIO */ 132 /* 133 * FreeBSD does not have SIGPWR signal, map Linux SIGPWR signal 134 * to the first unused FreeBSD signal number. Since Linux supports 135 * signals from 1 to 64 we are ok here as our SIGRTMIN = 65. 136 */ 137 LINUX_SIGPWREMU,/* LINUX_SIGPWR */ 138 SIGSYS /* LINUX_SIGSYS */ 139 }; 140 141 static struct cdev *dev_shm_cdev; 142 static struct cdevsw dev_shm_cdevsw = { 143 .d_version = D_VERSION, 144 .d_name = "dev_shm", 145 }; 146 147 /* 148 * Map Linux RT signals to the FreeBSD RT signals. 149 */ 150 static inline int 151 linux_to_bsd_rt_signal(int sig) 152 { 153 154 return (SIGRTMIN + sig - LINUX_SIGRTMIN); 155 } 156 157 static inline int 158 bsd_to_linux_rt_signal(int sig) 159 { 160 161 return (sig - SIGRTMIN + LINUX_SIGRTMIN); 162 } 163 164 int 165 linux_to_bsd_signal(int sig) 166 { 167 168 KASSERT(sig > 0 && sig <= LINUX_SIGRTMAX, ("invalid Linux signal %d\n", sig)); 169 170 if (sig < LINUX_SIGRTMIN) 171 return (linux_to_bsd_sigtbl[_SIG_IDX(sig)]); 172 173 return (linux_to_bsd_rt_signal(sig)); 174 } 175 176 int 177 bsd_to_linux_signal(int sig) 178 { 179 180 if (sig <= LINUX_SIGTBLSZ) 181 return (bsd_to_linux_sigtbl[_SIG_IDX(sig)]); 182 if (sig == LINUX_SIGPWREMU) 183 return (LINUX_SIGPWR); 184 185 return (bsd_to_linux_rt_signal(sig)); 186 } 187 188 int 189 linux_to_bsd_sigaltstack(int lsa) 190 { 191 int bsa = 0; 192 193 if (lsa & LINUX_SS_DISABLE) 194 bsa |= SS_DISABLE; 195 /* 196 * Linux ignores SS_ONSTACK flag for ss 197 * parameter while FreeBSD prohibits it. 198 */ 199 return (bsa); 200 } 201 202 int 203 bsd_to_linux_sigaltstack(int bsa) 204 { 205 int lsa = 0; 206 207 if (bsa & SS_DISABLE) 208 lsa |= LINUX_SS_DISABLE; 209 if (bsa & SS_ONSTACK) 210 lsa |= LINUX_SS_ONSTACK; 211 return (lsa); 212 } 213 214 void 215 linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss) 216 { 217 int b, l; 218 219 SIGEMPTYSET(*bss); 220 for (l = 1; l <= LINUX_SIGRTMAX; l++) { 221 if (LINUX_SIGISMEMBER(*lss, l)) { 222 b = linux_to_bsd_signal(l); 223 if (b) 224 SIGADDSET(*bss, b); 225 } 226 } 227 } 228 229 void 230 bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) 231 { 232 int b, l; 233 234 LINUX_SIGEMPTYSET(*lss); 235 for (b = 1; b <= SIGRTMAX; b++) { 236 if (SIGISMEMBER(*bss, b)) { 237 l = bsd_to_linux_signal(b); 238 if (l) 239 LINUX_SIGADDSET(*lss, l); 240 } 241 } 242 } 243 244 /* 245 * Translate a Linux interface name to a FreeBSD interface name, 246 * and return the associated ifnet structure 247 * bsdname and lxname need to be least IFNAMSIZ bytes long, but 248 * can point to the same buffer. 249 */ 250 struct ifnet * 251 ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname) 252 { 253 struct ifnet *ifp; 254 int len, unit; 255 char *ep; 256 int index; 257 bool is_eth, is_lo; 258 259 for (len = 0; len < LINUX_IFNAMSIZ; ++len) 260 if (!isalpha(lxname[len]) || lxname[len] == '\0') 261 break; 262 if (len == 0 || len == LINUX_IFNAMSIZ) 263 return (NULL); 264 /* Linux loopback interface name is lo (not lo0) */ 265 is_lo = (len == 2 && strncmp(lxname, "lo", len) == 0); 266 unit = (int)strtoul(lxname + len, &ep, 10); 267 if ((ep == NULL || ep == lxname + len || ep >= lxname + LINUX_IFNAMSIZ) && 268 is_lo == 0) 269 return (NULL); 270 index = 0; 271 is_eth = (len == 3 && strncmp(lxname, "eth", len) == 0); 272 273 CURVNET_SET(TD_TO_VNET(td)); 274 IFNET_RLOCK(); 275 CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { 276 /* 277 * Allow Linux programs to use FreeBSD names. Don't presume 278 * we never have an interface named "eth", so don't make 279 * the test optional based on is_eth. 280 */ 281 if (strncmp(ifp->if_xname, lxname, LINUX_IFNAMSIZ) == 0) 282 break; 283 if (is_eth && IFP_IS_ETH(ifp) && unit == index++) 284 break; 285 if (is_lo && IFP_IS_LOOP(ifp)) 286 break; 287 } 288 IFNET_RUNLOCK(); 289 CURVNET_RESTORE(); 290 if (ifp != NULL && bsdname != NULL) 291 strlcpy(bsdname, ifp->if_xname, IFNAMSIZ); 292 return (ifp); 293 } 294 295 void 296 linux_ifflags(struct ifnet *ifp, short *flags) 297 { 298 unsigned short fl; 299 300 fl = (ifp->if_flags | ifp->if_drv_flags) & 0xffff; 301 *flags = 0; 302 if (fl & IFF_UP) 303 *flags |= LINUX_IFF_UP; 304 if (fl & IFF_BROADCAST) 305 *flags |= LINUX_IFF_BROADCAST; 306 if (fl & IFF_DEBUG) 307 *flags |= LINUX_IFF_DEBUG; 308 if (fl & IFF_LOOPBACK) 309 *flags |= LINUX_IFF_LOOPBACK; 310 if (fl & IFF_POINTOPOINT) 311 *flags |= LINUX_IFF_POINTOPOINT; 312 if (fl & IFF_DRV_RUNNING) 313 *flags |= LINUX_IFF_RUNNING; 314 if (fl & IFF_NOARP) 315 *flags |= LINUX_IFF_NOARP; 316 if (fl & IFF_PROMISC) 317 *flags |= LINUX_IFF_PROMISC; 318 if (fl & IFF_ALLMULTI) 319 *flags |= LINUX_IFF_ALLMULTI; 320 if (fl & IFF_MULTICAST) 321 *flags |= LINUX_IFF_MULTICAST; 322 } 323 324 int 325 linux_ifhwaddr(struct ifnet *ifp, struct l_sockaddr *lsa) 326 { 327 struct ifaddr *ifa; 328 struct sockaddr_dl *sdl; 329 330 if (IFP_IS_LOOP(ifp)) { 331 bzero(lsa, sizeof(*lsa)); 332 lsa->sa_family = LINUX_ARPHRD_LOOPBACK; 333 return (0); 334 } 335 336 if (!IFP_IS_ETH(ifp)) 337 return (ENOENT); 338 339 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 340 sdl = (struct sockaddr_dl*)ifa->ifa_addr; 341 if (sdl != NULL && (sdl->sdl_family == AF_LINK) && 342 (sdl->sdl_type == IFT_ETHER)) { 343 bzero(lsa, sizeof(*lsa)); 344 lsa->sa_family = LINUX_ARPHRD_ETHER; 345 bcopy(LLADDR(sdl), lsa->sa_data, LINUX_IFHWADDRLEN); 346 return (0); 347 } 348 } 349 350 return (ENOENT); 351 } 352 353 int 354 linux_to_bsd_domain(int domain) 355 { 356 357 switch (domain) { 358 case LINUX_AF_UNSPEC: 359 return (AF_UNSPEC); 360 case LINUX_AF_UNIX: 361 return (AF_LOCAL); 362 case LINUX_AF_INET: 363 return (AF_INET); 364 case LINUX_AF_INET6: 365 return (AF_INET6); 366 case LINUX_AF_AX25: 367 return (AF_CCITT); 368 case LINUX_AF_IPX: 369 return (AF_IPX); 370 case LINUX_AF_APPLETALK: 371 return (AF_APPLETALK); 372 case LINUX_AF_NETLINK: 373 return (AF_NETLINK); 374 } 375 return (-1); 376 } 377 378 int 379 bsd_to_linux_domain(int domain) 380 { 381 382 switch (domain) { 383 case AF_UNSPEC: 384 return (LINUX_AF_UNSPEC); 385 case AF_LOCAL: 386 return (LINUX_AF_UNIX); 387 case AF_INET: 388 return (LINUX_AF_INET); 389 case AF_INET6: 390 return (LINUX_AF_INET6); 391 case AF_CCITT: 392 return (LINUX_AF_AX25); 393 case AF_IPX: 394 return (LINUX_AF_IPX); 395 case AF_APPLETALK: 396 return (LINUX_AF_APPLETALK); 397 case AF_NETLINK: 398 return (LINUX_AF_NETLINK); 399 } 400 return (-1); 401 } 402 403 /* 404 * Based on the fact that: 405 * 1. Native and Linux storage of struct sockaddr 406 * and struct sockaddr_in6 are equal. 407 * 2. On Linux sa_family is the first member of all struct sockaddr. 408 */ 409 int 410 bsd_to_linux_sockaddr(const struct sockaddr *sa, struct l_sockaddr **lsa, 411 socklen_t len) 412 { 413 struct l_sockaddr *kosa; 414 int bdom; 415 416 *lsa = NULL; 417 if (len < 2 || len > UCHAR_MAX) 418 return (EINVAL); 419 bdom = bsd_to_linux_domain(sa->sa_family); 420 if (bdom == -1) 421 return (EAFNOSUPPORT); 422 423 kosa = malloc(len, M_LINUX, M_WAITOK); 424 bcopy(sa, kosa, len); 425 kosa->sa_family = bdom; 426 *lsa = kosa; 427 return (0); 428 } 429 430 int 431 linux_to_bsd_sockaddr(const struct l_sockaddr *osa, struct sockaddr **sap, 432 socklen_t *len) 433 { 434 struct sockaddr *sa; 435 struct l_sockaddr *kosa; 436 #ifdef INET6 437 struct sockaddr_in6 *sin6; 438 bool oldv6size; 439 #endif 440 char *name; 441 int salen, bdom, error, hdrlen, namelen; 442 443 if (*len < 2 || *len > UCHAR_MAX) 444 return (EINVAL); 445 446 salen = *len; 447 448 #ifdef INET6 449 oldv6size = false; 450 /* 451 * Check for old (pre-RFC2553) sockaddr_in6. We may accept it 452 * if it's a v4-mapped address, so reserve the proper space 453 * for it. 454 */ 455 if (salen == sizeof(struct sockaddr_in6) - sizeof(uint32_t)) { 456 salen += sizeof(uint32_t); 457 oldv6size = true; 458 } 459 #endif 460 461 kosa = malloc(salen, M_SONAME, M_WAITOK); 462 463 if ((error = copyin(osa, kosa, *len))) 464 goto out; 465 466 bdom = linux_to_bsd_domain(kosa->sa_family); 467 if (bdom == -1) { 468 error = EAFNOSUPPORT; 469 goto out; 470 } 471 472 #ifdef INET6 473 /* 474 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6, 475 * which lacks the scope id compared with RFC2553 one. If we detect 476 * the situation, reject the address and write a message to system log. 477 * 478 * Still accept addresses for which the scope id is not used. 479 */ 480 if (oldv6size) { 481 if (bdom == AF_INET6) { 482 sin6 = (struct sockaddr_in6 *)kosa; 483 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) || 484 (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && 485 !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && 486 !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) && 487 !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && 488 !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) { 489 sin6->sin6_scope_id = 0; 490 } else { 491 linux_msg(curthread, 492 "obsolete pre-RFC2553 sockaddr_in6 rejected"); 493 error = EINVAL; 494 goto out; 495 } 496 } else 497 salen -= sizeof(uint32_t); 498 } 499 #endif 500 if (bdom == AF_INET) { 501 if (salen < sizeof(struct sockaddr_in)) { 502 error = EINVAL; 503 goto out; 504 } 505 salen = sizeof(struct sockaddr_in); 506 } 507 508 if (bdom == AF_LOCAL && salen > sizeof(struct sockaddr_un)) { 509 hdrlen = offsetof(struct sockaddr_un, sun_path); 510 name = ((struct sockaddr_un *)kosa)->sun_path; 511 if (*name == '\0') { 512 /* 513 * Linux abstract namespace starts with a NULL byte. 514 * XXX We do not support abstract namespace yet. 515 */ 516 namelen = strnlen(name + 1, salen - hdrlen - 1) + 1; 517 } else 518 namelen = strnlen(name, salen - hdrlen); 519 salen = hdrlen + namelen; 520 if (salen > sizeof(struct sockaddr_un)) { 521 error = ENAMETOOLONG; 522 goto out; 523 } 524 } 525 526 if (bdom == AF_NETLINK) { 527 if (salen < sizeof(struct sockaddr_nl)) { 528 error = EINVAL; 529 goto out; 530 } 531 salen = sizeof(struct sockaddr_nl); 532 } 533 534 sa = (struct sockaddr *)kosa; 535 sa->sa_family = bdom; 536 sa->sa_len = salen; 537 538 *sap = sa; 539 *len = salen; 540 return (0); 541 542 out: 543 free(kosa, M_SONAME); 544 return (error); 545 } 546 547 void 548 linux_dev_shm_create(void) 549 { 550 int error; 551 552 error = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, &dev_shm_cdev, 553 &dev_shm_cdevsw, NULL, UID_ROOT, GID_WHEEL, 0, "shm/.mountpoint"); 554 if (error != 0) { 555 printf("%s: failed to create device node, error %d\n", 556 __func__, error); 557 } 558 } 559 560 void 561 linux_dev_shm_destroy(void) 562 { 563 564 destroy_dev(dev_shm_cdev); 565 } 566 567 int 568 bsd_to_linux_bits_(int value, struct bsd_to_linux_bitmap *bitmap, 569 size_t mapcnt, int no_value) 570 { 571 int bsd_mask, bsd_value, linux_mask, linux_value; 572 int linux_ret; 573 size_t i; 574 bool applied; 575 576 applied = false; 577 linux_ret = 0; 578 for (i = 0; i < mapcnt; ++i) { 579 bsd_mask = bitmap[i].bsd_mask; 580 bsd_value = bitmap[i].bsd_value; 581 if (bsd_mask == 0) 582 bsd_mask = bsd_value; 583 584 linux_mask = bitmap[i].linux_mask; 585 linux_value = bitmap[i].linux_value; 586 if (linux_mask == 0) 587 linux_mask = linux_value; 588 589 /* 590 * If a mask larger than just the value is set, we explicitly 591 * want to make sure that only this bit we mapped within that 592 * mask is set. 593 */ 594 if ((value & bsd_mask) == bsd_value) { 595 linux_ret = (linux_ret & ~linux_mask) | linux_value; 596 applied = true; 597 } 598 } 599 600 if (!applied) 601 return (no_value); 602 return (linux_ret); 603 } 604 605 int 606 linux_to_bsd_bits_(int value, struct bsd_to_linux_bitmap *bitmap, 607 size_t mapcnt, int no_value) 608 { 609 int bsd_mask, bsd_value, linux_mask, linux_value; 610 int bsd_ret; 611 size_t i; 612 bool applied; 613 614 applied = false; 615 bsd_ret = 0; 616 for (i = 0; i < mapcnt; ++i) { 617 bsd_mask = bitmap[i].bsd_mask; 618 bsd_value = bitmap[i].bsd_value; 619 if (bsd_mask == 0) 620 bsd_mask = bsd_value; 621 622 linux_mask = bitmap[i].linux_mask; 623 linux_value = bitmap[i].linux_value; 624 if (linux_mask == 0) 625 linux_mask = linux_value; 626 627 /* 628 * If a mask larger than just the value is set, we explicitly 629 * want to make sure that only this bit we mapped within that 630 * mask is set. 631 */ 632 if ((value & linux_mask) == linux_value) { 633 bsd_ret = (bsd_ret & ~bsd_mask) | bsd_value; 634 applied = true; 635 } 636 } 637 638 if (!applied) 639 return (no_value); 640 return (bsd_ret); 641 } 642 643 void 644 linux_to_bsd_poll_events(struct thread *td, int fd, short lev, 645 short *bev) 646 { 647 struct file *fp; 648 int error; 649 short bits = 0; 650 651 if (lev & LINUX_POLLIN) 652 bits |= POLLIN; 653 if (lev & LINUX_POLLPRI) 654 bits |= POLLPRI; 655 if (lev & LINUX_POLLOUT) 656 bits |= POLLOUT; 657 if (lev & LINUX_POLLERR) 658 bits |= POLLERR; 659 if (lev & LINUX_POLLHUP) 660 bits |= POLLHUP; 661 if (lev & LINUX_POLLNVAL) 662 bits |= POLLNVAL; 663 if (lev & LINUX_POLLRDNORM) 664 bits |= POLLRDNORM; 665 if (lev & LINUX_POLLRDBAND) 666 bits |= POLLRDBAND; 667 if (lev & LINUX_POLLWRBAND) 668 bits |= POLLWRBAND; 669 if (lev & LINUX_POLLWRNORM) 670 bits |= POLLWRNORM; 671 672 if (lev & LINUX_POLLRDHUP) { 673 /* 674 * It seems that the Linux silencly ignores POLLRDHUP 675 * on non-socket file descriptors unlike FreeBSD, where 676 * events bits is more strictly checked (POLLSTANDARD). 677 */ 678 error = fget_unlocked(td, fd, &cap_no_rights, &fp); 679 if (error == 0) { 680 /* 681 * XXX. On FreeBSD POLLRDHUP applies only to 682 * stream sockets. 683 */ 684 if (fp->f_type == DTYPE_SOCKET) 685 bits |= POLLRDHUP; 686 fdrop(fp, td); 687 } 688 } 689 690 if (lev & LINUX_POLLMSG) 691 LINUX_RATELIMIT_MSG_OPT1("unsupported POLLMSG, events(%d)", lev); 692 if (lev & LINUX_POLLREMOVE) 693 LINUX_RATELIMIT_MSG_OPT1("unsupported POLLREMOVE, events(%d)", lev); 694 695 *bev = bits; 696 } 697 698 void 699 bsd_to_linux_poll_events(short bev, short *lev) 700 { 701 short bits = 0; 702 703 if (bev & POLLIN) 704 bits |= LINUX_POLLIN; 705 if (bev & POLLPRI) 706 bits |= LINUX_POLLPRI; 707 if (bev & (POLLOUT | POLLWRNORM)) 708 /* 709 * POLLWRNORM is equal to POLLOUT on FreeBSD, 710 * but not on Linux 711 */ 712 bits |= LINUX_POLLOUT; 713 if (bev & POLLERR) 714 bits |= LINUX_POLLERR; 715 if (bev & POLLHUP) 716 bits |= LINUX_POLLHUP; 717 if (bev & POLLNVAL) 718 bits |= LINUX_POLLNVAL; 719 if (bev & POLLRDNORM) 720 bits |= LINUX_POLLRDNORM; 721 if (bev & POLLRDBAND) 722 bits |= LINUX_POLLRDBAND; 723 if (bev & POLLWRBAND) 724 bits |= LINUX_POLLWRBAND; 725 if (bev & POLLRDHUP) 726 bits |= LINUX_POLLRDHUP; 727 728 *lev = bits; 729 } 730 731 bool 732 linux_use_real_ifname(const struct ifnet *ifp) 733 { 734 735 return (use_real_ifnames || !IFP_IS_ETH(ifp)); 736 } 737