* clone - meaningful only for bsdi and freebsd */
| 619 | * clone - meaningful only for bsdi and freebsd |
| 620 | */ |
| 621 | static int |
| 622 | selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, |
| 623 | struct ip6_moptions *mopts, struct route_in6 *ro, |
| 624 | struct ifnet **retifp, struct nhop_object **retnh, int norouteok, |
| 625 | u_int fibnum, uint32_t flowid) |
| 626 | { |
| 627 | int error = 0; |
| 628 | struct ifnet *ifp = NULL; |
| 629 | struct nhop_object *nh = NULL; |
| 630 | struct sockaddr_in6 *sin6_next; |
| 631 | struct in6_pktinfo *pi = NULL; |
| 632 | struct in6_addr *dst = &dstsock->sin6_addr; |
| 633 | uint32_t zoneid; |
| 634 | #if 0 |
| 635 | char ip6buf[INET6_ADDRSTRLEN]; |
| 636 | |
| 637 | if (dstsock->sin6_addr.s6_addr32[0] == 0 && |
| 638 | dstsock->sin6_addr.s6_addr32[1] == 0 && |
| 639 | !IN6_IS_ADDR_LOOPBACK(&dstsock->sin6_addr)) { |
| 640 | printf("%s: strange destination %s\n", __func__, |
| 641 | ip6_sprintf(ip6buf, &dstsock->sin6_addr)); |
| 642 | } else { |
| 643 | printf("%s: destination = %s%%%d\n", __func__, |
| 644 | ip6_sprintf(ip6buf, &dstsock->sin6_addr), |
| 645 | dstsock->sin6_scope_id); /* for debug */ |
| 646 | } |
| 647 | #endif |
| 648 | |
| 649 | /* If the caller specify the outgoing interface explicitly, use it. */ |
| 650 | if (opts && (pi = opts->ip6po_pktinfo) != NULL && pi->ipi6_ifindex) { |
| 651 | /* XXX boundary check is assumed to be already done. */ |
| 652 | ifp = ifnet_byindex(pi->ipi6_ifindex); |
| 653 | if (ifp != NULL && |
| 654 | (norouteok || retnh == NULL || |
| 655 | IN6_IS_ADDR_MULTICAST(dst))) { |
| 656 | /* |
| 657 | * we do not have to check or get the route for |
| 658 | * multicast. |
| 659 | */ |
| 660 | goto done; |
| 661 | } else |
| 662 | goto getroute; |
| 663 | } |
| 664 | /* |
| 665 | * If the destination address is a multicast address and the outgoing |
| 666 | * interface for the address is specified by the caller, use it. |
| 667 | */ |
| 668 | if (IN6_IS_ADDR_MULTICAST(dst) && |
| 669 | mopts != NULL && (ifp = mopts->im6o_multicast_ifp) != NULL) { |
| 670 | goto done; /* we do not need a route for multicast. */ |
| 671 | } |
| 672 | /* |
| 673 | * If destination address is LLA or link- or node-local multicast, |
| 674 | * use it's embedded scope zone id to determine outgoing interface. |
| 675 | */ |
| 676 | if (IN6_IS_ADDR_MC_LINKLOCAL(dst) || |
| 677 | IN6_IS_ADDR_MC_NODELOCAL(dst)) { |
| 678 | zoneid = ntohs(in6_getscope(dst)); |
no test coverage detected