Index: head/sys/net/debugnet.c =================================================================== --- head/sys/net/debugnet.c +++ head/sys/net/debugnet.c @@ -53,8 +53,11 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -644,8 +647,8 @@ if (pcb->dp_client == INADDR_ANY || pcb->dp_gateway == INADDR_ANY || pcb->dp_ifp == NULL) { struct sockaddr_in dest_sin, *gw_sin, *local_sin; - struct rtentry *dest_rt; struct ifnet *rt_ifp; + struct nhop_object *nh; memset(&dest_sin, 0, sizeof(dest_sin)); dest_sin = (struct sockaddr_in) { @@ -655,29 +658,29 @@ }; CURVNET_SET(vnet0); - dest_rt = rtalloc1((struct sockaddr *)&dest_sin, 0, - RTF_RNH_LOCKED); + nh = fib4_lookup_debugnet(RT_DEFAULT_FIB, dest_sin.sin_addr, 0, + NHR_NONE); CURVNET_RESTORE(); - if (dest_rt == NULL) { + if (nh == NULL) { printf("%s: Could not get route for that server.\n", __func__); error = ENOENT; goto cleanup; } - if (dest_rt->rt_gateway->sa_family == AF_INET) - gw_sin = (struct sockaddr_in *)dest_rt->rt_gateway; + if (nh->gw_sa.sa_family == AF_INET) + gw_sin = &nh->gw4_sa; else { - if (dest_rt->rt_gateway->sa_family == AF_LINK) + if (nh->gw_sa.sa_family == AF_LINK) DNETDEBUG("Destination address is on link.\n"); gw_sin = NULL; } - MPASS(dest_rt->rt_ifa->ifa_addr->sa_family == AF_INET); - local_sin = (struct sockaddr_in *)dest_rt->rt_ifa->ifa_addr; + MPASS(nh->nh_ifa->ifa_addr->sa_family == AF_INET); + local_sin = (struct sockaddr_in *)nh->nh_ifa->ifa_addr; - rt_ifp = dest_rt->rt_ifp; + rt_ifp = nh->nh_ifp; if (pcb->dp_client == INADDR_ANY) pcb->dp_client = local_sin->sin_addr.s_addr; @@ -685,8 +688,6 @@ pcb->dp_gateway = gw_sin->sin_addr.s_addr; if (pcb->dp_ifp == NULL) pcb->dp_ifp = rt_ifp; - - RTFREE_LOCKED(dest_rt); } ifp = pcb->dp_ifp; Index: head/sys/netinet/in_fib.h =================================================================== --- head/sys/netinet/in_fib.h +++ head/sys/netinet/in_fib.h @@ -75,5 +75,7 @@ uint32_t scopeid, uint32_t flags, uint32_t flowid); int fib4_check_urpf(uint32_t fibnum, struct in_addr dst, uint32_t scopeid, uint32_t flags, const struct ifnet *src_if); +struct nhop_object *fib4_lookup_debugnet(uint32_t fibnum, struct in_addr dst, + uint32_t scopeid, uint32_t flags); #endif Index: head/sys/netinet/in_fib.c =================================================================== --- head/sys/netinet/in_fib.c +++ head/sys/netinet/in_fib.c @@ -361,4 +361,46 @@ return (0); } +struct nhop_object * +fib4_lookup_debugnet(uint32_t fibnum, struct in_addr dst, uint32_t scopeid, + uint32_t flags) +{ + struct rib_head *rh; + struct radix_node *rn; + struct rtentry *rt; + struct nhop_object *nh; + + KASSERT((fibnum < rt_numfibs), ("fib4_lookup_debugnet: bad fibnum")); + rh = rt_tables_get_rnh(fibnum, AF_INET); + if (rh == NULL) + return (NULL); + + /* Prepare lookup key */ + struct sockaddr_in sin4; + memset(&sin4, 0, sizeof(sin4)); + sin4.sin_family = AF_INET; + sin4.sin_len = sizeof(struct sockaddr_in); + sin4.sin_addr = dst; + + nh = NULL; + /* unlocked lookup */ + rn = rh->rnh_matchaddr((void *)&sin4, &rh->head); + if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { + rt = RNTORT(rn); +#ifdef RADIX_MPATH + if (rt_mpath_next(rt) != NULL) + rt = rt_mpath_selectrte(rt, 0); +#endif + nh = rt->rt_nhop; + /* Ensure route & ifp is UP */ + if (RT_LINK_IS_UP(nh->nh_ifp)) { + if (flags & NHR_REF) + nhop_ref_object(nh); + return (nh); + } + } + + return (NULL); +} + #endif Index: head/sys/netinet6/in6_fib.h =================================================================== --- head/sys/netinet6/in6_fib.h +++ head/sys/netinet6/in6_fib.h @@ -64,5 +64,7 @@ uint32_t flowid); int fib6_check_urpf(uint32_t fibnum, const struct in6_addr *dst6, uint32_t scopeid, uint32_t flags, const struct ifnet *src_if); +struct nhop_object *fib6_lookup_debugnet(uint32_t fibnum, + const struct in6_addr *dst6, uint32_t scopeid, uint32_t flags); #endif Index: head/sys/netinet6/in6_fib.c =================================================================== --- head/sys/netinet6/in6_fib.c +++ head/sys/netinet6/in6_fib.c @@ -397,5 +397,46 @@ return (0); } +struct nhop_object * +fib6_lookup_debugnet(uint32_t fibnum, const struct in6_addr *dst6, + uint32_t scopeid, uint32_t flags) +{ + struct rib_head *rh; + struct radix_node *rn; + struct rtentry *rt; + struct nhop_object *nh; + struct sockaddr_in6 sin6; + + KASSERT((fibnum < rt_numfibs), ("fib6_lookup: bad fibnum")); + rh = rt_tables_get_rnh(fibnum, AF_INET6); + if (rh == NULL) + return (NULL); + + /* TODO: radix changes */ + //addr = *dst6; + /* Prepare lookup key */ + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_addr = *dst6; + + /* Assume scopeid is valid and embed it directly */ + if (IN6_IS_SCOPE_LINKLOCAL(dst6)) + sin6.sin6_addr.s6_addr16[1] = htons(scopeid & 0xffff); + + rn = rh->rnh_matchaddr((void *)&sin6, &rh->head); + if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { + rt = RNTORT(rn); + nh = rt->rt_nhop; + /* Ensure route & ifp is UP */ + if (RT_LINK_IS_UP(nh->nh_ifp)) { + if (flags & NHR_REF) + nhop_ref_object(nh); + return (nh); + } + } + + return (NULL); +} + #endif