| 830 | } |
| 831 | |
| 832 | static int |
| 833 | in6_selectif(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, |
| 834 | struct ip6_moptions *mopts, struct ifnet **retifp, |
| 835 | struct ifnet *oifp, u_int fibnum) |
| 836 | { |
| 837 | int error; |
| 838 | struct route_in6 sro; |
| 839 | struct nhop_object *nh = NULL; |
| 840 | uint16_t nh_flags; |
| 841 | |
| 842 | KASSERT(retifp != NULL, ("%s: retifp is NULL", __func__)); |
| 843 | |
| 844 | bzero(&sro, sizeof(sro)); |
| 845 | nh_flags = 0; |
| 846 | |
| 847 | error = selectroute(dstsock, opts, mopts, &sro, retifp, &nh, 1, fibnum, 0); |
| 848 | |
| 849 | if (nh != NULL) |
| 850 | nh_flags = nh->nh_flags; |
| 851 | if (nh != NULL && nh == sro.ro_nh) |
| 852 | NH_FREE(nh); |
| 853 | |
| 854 | if (error != 0) { |
| 855 | /* Help ND. See oifp comment in in6_selectsrc(). */ |
| 856 | if (oifp != NULL && fibnum == RT_DEFAULT_FIB) { |
| 857 | *retifp = oifp; |
| 858 | error = 0; |
| 859 | } |
| 860 | return (error); |
| 861 | } |
| 862 | |
| 863 | /* |
| 864 | * do not use a rejected or black hole route. |
| 865 | * XXX: this check should be done in the L2 output routine. |
| 866 | * However, if we skipped this check here, we'd see the following |
| 867 | * scenario: |
| 868 | * - install a rejected route for a scoped address prefix |
| 869 | * (like fe80::/10) |
| 870 | * - send a packet to a destination that matches the scoped prefix, |
| 871 | * with ambiguity about the scope zone. |
| 872 | * - pick the outgoing interface from the route, and disambiguate the |
| 873 | * scope zone with the interface. |
| 874 | * - ip6_output() would try to get another route with the "new" |
| 875 | * destination, which may be valid. |
| 876 | * - we'd see no error on output. |
| 877 | * Although this may not be very harmful, it should still be confusing. |
| 878 | * We thus reject the case here. |
| 879 | */ |
| 880 | |
| 881 | if (nh_flags & (NHF_REJECT | NHF_BLACKHOLE)) { |
| 882 | error = (nh_flags & NHF_HOST ? EHOSTUNREACH : ENETUNREACH); |
| 883 | return (error); |
| 884 | } |
| 885 | |
| 886 | return (0); |
| 887 | } |
| 888 | |
| 889 | /* Public wrapper function to selectroute(). */ |
no test coverage detected