Convert debugnet to the new routing KPI.
Introduce new fib[46]_lookup_debugnet() functions serving as a special interface for the crash-time operations. Underlying implementation will try to return lookup result if datastructures are not corrupted, avoding locking. Convert debugnet to use fib4_lookup_debugnet() and switch it to use nexthops instead of rtentries. Reviewed by: cem Differential Revision: https://reviews.freebsd.org/D24555
This commit is contained in:
parent
49c9f84f54
commit
55f57ca9ac
@ -53,8 +53,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/route.h>
|
||||
#include <net/route/nhop.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_fib.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/ip.h>
|
||||
@ -644,8 +647,8 @@ debugnet_connect(const struct debugnet_conn_params *dcp,
|
||||
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 @@ debugnet_connect(const struct debugnet_conn_params *dcp,
|
||||
};
|
||||
|
||||
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 @@ debugnet_connect(const struct debugnet_conn_params *dcp,
|
||||
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;
|
||||
|
@ -361,4 +361,46 @@ fib4_check_urpf(uint32_t fibnum, struct in_addr dst, uint32_t scopeid,
|
||||
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
|
||||
|
@ -75,5 +75,7 @@ struct nhop_object *fib4_lookup(uint32_t fibnum, struct in_addr dst,
|
||||
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
|
||||
|
||||
|
@ -397,5 +397,46 @@ fib6_check_urpf(uint32_t fibnum, const struct in6_addr *dst6,
|
||||
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
|
||||
|
||||
|
@ -64,5 +64,7 @@ struct nhop_object *fib6_lookup(uint32_t fibnum,
|
||||
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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user