From owner-svn-src-head@freebsd.org Thu Dec 3 22:23:58 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 9DB824B169B; Thu, 3 Dec 2020 22:23:58 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Cn9NZ44ZYz4r5x; Thu, 3 Dec 2020 22:23:58 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7EC7120DCC; Thu, 3 Dec 2020 22:23:58 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0B3MNwAh009444; Thu, 3 Dec 2020 22:23:58 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0B3MNvcc009440; Thu, 3 Dec 2020 22:23:57 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <202012032223.0B3MNvcc009440@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Thu, 3 Dec 2020 22:23:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r368317 - head/sys/net/route X-SVN-Group: head X-SVN-Commit-Author: melifaro X-SVN-Commit-Paths: head/sys/net/route X-SVN-Commit-Revision: 368317 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Dec 2020 22:23:58 -0000 Author: melifaro Date: Thu Dec 3 22:23:57 2020 New Revision: 368317 URL: https://svnweb.freebsd.org/changeset/base/368317 Log: Add IPv4/IPv6 rtentry prefix accessors. Multiple consumers like ipfw, netflow or new route lookup algorithms need to get the prefix data out of struct rtentry. Instead of providing direct access to the rtentry, create IPv4/IPv6 accessors to abstract struct rtentry internals and avoid including internal routing headers for external consumers. While here, move struct route_nhop_data to the public header, so external customers can actually use lookup functions returning rt&nhop data. Differential Revision: https://reviews.freebsd.org/D27416 Modified: head/sys/net/route/route_ctl.c head/sys/net/route/route_ctl.h head/sys/net/route/route_var.h Modified: head/sys/net/route/route_ctl.c ============================================================================== --- head/sys/net/route/route_ctl.c Thu Dec 3 22:06:08 2020 (r368316) +++ head/sys/net/route/route_ctl.c Thu Dec 3 22:23:57 2020 (r368317) @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -235,6 +236,132 @@ get_info_weight(const struct rt_addrinfo *info, uint32 return (weight); } + +bool +rt_is_host(const struct rtentry *rt) +{ + + return (rt->rte_flags & RTF_HOST); +} + +/* + * Returns pointer to nexthop or nexthop group + * associated with @rt + */ +struct nhop_object * +rt_get_raw_nhop(const struct rtentry *rt) +{ + + return (rt->rt_nhop); +} + +#ifdef INET +/* + * Stores IPv4 address and prefix length of @rt inside + * @paddr and @plen. + * @pscopeid is currently always set to 0. + */ +void +rt_get_inet_prefix_plen(const struct rtentry *rt, struct in_addr *paddr, + int *plen, uint32_t *pscopeid) +{ + const struct sockaddr_in *dst; + + dst = (const struct sockaddr_in *)rt_key_const(rt); + KASSERT((dst->sin_family == AF_INET), + ("rt family is %d, not inet", dst->sin_family)); + *paddr = dst->sin_addr; + dst = (const struct sockaddr_in *)rt_mask_const(rt); + if (dst == NULL) + *plen = 32; + else + *plen = bitcount32(dst->sin_addr.s_addr); + *pscopeid = 0; +} + +/* + * Stores IPv4 address and prefix mask of @rt inside + * @paddr and @pmask. Sets mask to INADDR_ANY for host routes. + * @pscopeid is currently always set to 0. + */ +void +rt_get_inet_prefix_pmask(const struct rtentry *rt, struct in_addr *paddr, + struct in_addr *pmask, uint32_t *pscopeid) +{ + const struct sockaddr_in *dst; + + dst = (const struct sockaddr_in *)rt_key_const(rt); + KASSERT((dst->sin_family == AF_INET), + ("rt family is %d, not inet", dst->sin_family)); + *paddr = dst->sin_addr; + dst = (const struct sockaddr_in *)rt_mask_const(rt); + if (dst == NULL) + pmask->s_addr = INADDR_BROADCAST; + else + *pmask = dst->sin_addr; + *pscopeid = 0; +} +#endif + +#ifdef INET6 +static int +inet6_get_plen(const struct in6_addr *addr) +{ + + return (bitcount32(addr->s6_addr32[0]) + bitcount32(addr->s6_addr32[1]) + + bitcount32(addr->s6_addr32[2]) + bitcount32(addr->s6_addr32[3])); +} + +/* + * Stores IPv6 address and prefix length of @rt inside + * @paddr and @plen. Addresses are returned in de-embedded form. + * Scopeid is set to 0 for non-LL addresses. + */ +void +rt_get_inet6_prefix_plen(const struct rtentry *rt, struct in6_addr *paddr, + int *plen, uint32_t *pscopeid) +{ + const struct sockaddr_in6 *dst; + + dst = (const struct sockaddr_in6 *)rt_key_const(rt); + KASSERT((dst->sin6_family == AF_INET6), + ("rt family is %d, not inet6", dst->sin6_family)); + if (IN6_IS_SCOPE_LINKLOCAL(&dst->sin6_addr)) + in6_splitscope(&dst->sin6_addr, paddr, pscopeid); + else + *paddr = dst->sin6_addr; + dst = (const struct sockaddr_in6 *)rt_mask_const(rt); + if (dst == NULL) + *plen = 128; + else + *plen = inet6_get_plen(&dst->sin6_addr); +} + +/* + * Stores IPv6 address and prefix mask of @rt inside + * @paddr and @pmask. Addresses are returned in de-embedded form. + * Scopeid is set to 0 for non-LL addresses. + */ +void +rt_get_inet6_prefix_pmask(const struct rtentry *rt, struct in6_addr *paddr, + struct in6_addr *pmask, uint32_t *pscopeid) +{ + const struct sockaddr_in6 *dst; + + dst = (const struct sockaddr_in6 *)rt_key_const(rt); + KASSERT((dst->sin6_family == AF_INET6), + ("rt family is %d, not inet", dst->sin6_family)); + if (IN6_IS_SCOPE_LINKLOCAL(&dst->sin6_addr)) + in6_splitscope(&dst->sin6_addr, paddr, pscopeid); + else + *paddr = dst->sin6_addr; + dst = (const struct sockaddr_in6 *)rt_mask_const(rt); + if (dst == NULL) + memset(pmask, 0xFF, sizeof(struct in6_addr)); + else + *pmask = dst->sin6_addr; +} +#endif static void rt_set_expire_info(struct rtentry *rt, const struct rt_addrinfo *info) Modified: head/sys/net/route/route_ctl.h ============================================================================== --- head/sys/net/route/route_ctl.h Thu Dec 3 22:06:08 2020 (r368316) +++ head/sys/net/route/route_ctl.h Thu Dec 3 22:23:57 2020 (r368317) @@ -82,18 +82,44 @@ void rib_foreach_table_walk(int family, bool wlock, ri rib_walk_hook_f_t *hook_f, void *arg); void rib_foreach_table_walk_del(int family, rib_filter_f_t *filter_f, void *arg); -struct route_nhop_data; +struct nhop_object; +struct nhgrp_object; +struct route_nhop_data { + union { + struct nhop_object *rnd_nhop; + struct nhgrp_object *rnd_nhgrp; + }; + uint32_t rnd_weight; +}; + const struct rtentry *rib_lookup_prefix(uint32_t fibnum, int family, const struct sockaddr *dst, const struct sockaddr *netmask, struct route_nhop_data *rnd); const struct rtentry *rib_lookup_lpm(uint32_t fibnum, int family, const struct sockaddr *dst, struct route_nhop_data *rnd); +/* rtentry accessors */ +bool rt_is_host(const struct rtentry *rt); +struct nhop_object *rt_get_raw_nhop(const struct rtentry *rt); +#ifdef INET +struct in_addr; +void rt_get_inet_prefix_plen(const struct rtentry *rt, struct in_addr *paddr, + int *plen, uint32_t *pscopeid); +void rt_get_inet_prefix_pmask(const struct rtentry *rt, struct in_addr *paddr, + struct in_addr *pmask, uint32_t *pscopeid); +#endif +#ifdef INET6 +struct in6_addr; +void rt_get_inet6_prefix_plen(const struct rtentry *rt, struct in6_addr *paddr, + int *plen, uint32_t *pscopeid); +void rt_get_inet6_prefix_pmask(const struct rtentry *rt, struct in6_addr *paddr, + struct in6_addr *pmask, uint32_t *pscopeid); +#endif + /* Nexthops */ uint32_t nhops_get_count(struct rib_head *rh); /* Multipath */ -struct nhgrp_object; struct weightened_nhop; struct weightened_nhop *nhgrp_get_nhops(struct nhgrp_object *nhg, Modified: head/sys/net/route/route_var.h ============================================================================== --- head/sys/net/route/route_var.h Thu Dec 3 22:06:08 2020 (r368316) +++ head/sys/net/route/route_var.h Thu Dec 3 22:23:57 2020 (r368317) @@ -205,14 +205,7 @@ void tmproutes_init(struct rib_head *rh); void tmproutes_destroy(struct rib_head *rh); /* route_ctl.c */ -struct route_nhop_data { - union { - struct nhop_object *rnd_nhop; - struct nhgrp_object *rnd_nhgrp; - }; - uint32_t rnd_weight; -}; - +struct route_nhop_data; int change_route_nhop(struct rib_head *rnh, struct rtentry *rt, struct rt_addrinfo *info, struct route_nhop_data *rnd, struct rib_cmd_info *rc);