* Handles RTM_GET message from routing socket, returning matching rt. * * Returns: * 0 on success, with locked and referenced matching rt in @rt_nrt * errno of failure */
| 725 | * errno of failure |
| 726 | */ |
| 727 | static int |
| 728 | handle_rtm_get(struct rt_addrinfo *info, u_int fibnum, |
| 729 | struct rt_msghdr *rtm, struct rib_cmd_info *rc) |
| 730 | { |
| 731 | RIB_RLOCK_TRACKER; |
| 732 | struct rib_head *rnh; |
| 733 | struct nhop_object *nh; |
| 734 | sa_family_t saf; |
| 735 | |
| 736 | saf = info->rti_info[RTAX_DST]->sa_family; |
| 737 | |
| 738 | rnh = rt_tables_get_rnh(fibnum, saf); |
| 739 | if (rnh == NULL) |
| 740 | return (EAFNOSUPPORT); |
| 741 | |
| 742 | RIB_RLOCK(rnh); |
| 743 | |
| 744 | /* |
| 745 | * By (implicit) convention host route (one without netmask) |
| 746 | * means longest-prefix-match request and the route with netmask |
| 747 | * means exact-match lookup. |
| 748 | * As cleanup_xaddrs() cleans up info flags&addrs for the /32,/128 |
| 749 | * prefixes, use original data to check for the netmask presence. |
| 750 | */ |
| 751 | if ((rtm->rtm_addrs & RTA_NETMASK) == 0) { |
| 752 | /* |
| 753 | * Provide longest prefix match for |
| 754 | * address lookup (no mask). |
| 755 | * 'route -n get addr' |
| 756 | */ |
| 757 | rc->rc_rt = (struct rtentry *) rnh->rnh_matchaddr( |
| 758 | info->rti_info[RTAX_DST], &rnh->head); |
| 759 | } else |
| 760 | rc->rc_rt = (struct rtentry *) rnh->rnh_lookup( |
| 761 | info->rti_info[RTAX_DST], |
| 762 | info->rti_info[RTAX_NETMASK], &rnh->head); |
| 763 | |
| 764 | if (rc->rc_rt == NULL) { |
| 765 | RIB_RUNLOCK(rnh); |
| 766 | return (ESRCH); |
| 767 | } |
| 768 | |
| 769 | nh = select_nhop(rt_get_raw_nhop(rc->rc_rt), info->rti_info[RTAX_GATEWAY]); |
| 770 | if (nh == NULL) { |
| 771 | RIB_RUNLOCK(rnh); |
| 772 | return (ESRCH); |
| 773 | } |
| 774 | /* |
| 775 | * If performing proxied L2 entry insertion, and |
| 776 | * the actual PPP host entry is found, perform |
| 777 | * another search to retrieve the prefix route of |
| 778 | * the local end point of the PPP link. |
| 779 | * TODO: move this logic to userland. |
| 780 | */ |
| 781 | if (rtm->rtm_flags & RTF_ANNOUNCE) { |
| 782 | struct sockaddr laddr; |
| 783 | |
| 784 | if (nh->nh_ifp != NULL && |
no test coverage detected