Date: Sun, 26 Apr 2020 18:42:38 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r360349 - in head/sys: net netinet netinet6 Message-ID: <202004261842.03QIgcfR088475@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: melifaro Date: Sun Apr 26 18:42:38 2020 New Revision: 360349 URL: https://svnweb.freebsd.org/changeset/base/360349 Log: 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 Modified: head/sys/net/debugnet.c head/sys/netinet/in_fib.c head/sys/netinet/in_fib.h head/sys/netinet6/in6_fib.c head/sys/netinet6/in6_fib.h Modified: head/sys/net/debugnet.c ============================================================================== --- head/sys/net/debugnet.c Sun Apr 26 18:07:35 2020 (r360348) +++ head/sys/net/debugnet.c Sun Apr 26 18:42:38 2020 (r360349) @@ -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 *dc 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 *dc }; 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 *dc 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; Modified: head/sys/netinet/in_fib.c ============================================================================== --- head/sys/netinet/in_fib.c Sun Apr 26 18:07:35 2020 (r360348) +++ head/sys/netinet/in_fib.c Sun Apr 26 18:42:38 2020 (r360349) @@ -361,4 +361,46 @@ fib4_check_urpf(uint32_t fibnum, struct in_addr dst, u 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 Modified: head/sys/netinet/in_fib.h ============================================================================== --- head/sys/netinet/in_fib.h Sun Apr 26 18:07:35 2020 (r360348) +++ head/sys/netinet/in_fib.h Sun Apr 26 18:42:38 2020 (r360349) @@ -75,5 +75,7 @@ struct nhop_object *fib4_lookup(uint32_t fibnum, struc 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 Modified: head/sys/netinet6/in6_fib.c ============================================================================== --- head/sys/netinet6/in6_fib.c Sun Apr 26 18:07:35 2020 (r360348) +++ head/sys/netinet6/in6_fib.c Sun Apr 26 18:42:38 2020 (r360349) @@ -397,5 +397,46 @@ fib6_check_urpf(uint32_t fibnum, const struct in6_addr 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 Modified: head/sys/netinet6/in6_fib.h ============================================================================== --- head/sys/netinet6/in6_fib.h Sun Apr 26 18:07:35 2020 (r360348) +++ head/sys/netinet6/in6_fib.h Sun Apr 26 18:42:38 2020 (r360349) @@ -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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202004261842.03QIgcfR088475>