From owner-svn-src-all@freebsd.org Thu Jan 14 13:14:13 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A86ACA82A67; Thu, 14 Jan 2016 13:14:13 +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 mx1.freebsd.org (Postfix) with ESMTPS id 7C39617C5; Thu, 14 Jan 2016 13:14:13 +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 u0EDECHu099111; Thu, 14 Jan 2016 13:14:12 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0EDECtD099110; Thu, 14 Jan 2016 13:14:12 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201601141314.u0EDECtD099110@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Thu, 14 Jan 2016 13:14:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r293914 - head/sys/netgraph/netflow X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jan 2016 13:14:13 -0000 Author: melifaro Date: Thu Jan 14 13:14:12 2016 New Revision: 293914 URL: https://svnweb.freebsd.org/changeset/base/293914 Log: Make ng_netflow(9) use new routing KPI. Netflow module is supposed to store (along with fields like gateway address and interface index) matched netmask for each record. This (currently) requires returning individual route entries, instead of optimized next-hop structure. Given that, use control-plane rib_lookup_info() function to avoid accessing rtentries directly. While rib_lookup_info() might be slower, than fibX_lookup() flavours, it is more scalable than rtalloc1_fib(), because rtentry mutex is not acquired. Modified: head/sys/netgraph/netflow/netflow.c Modified: head/sys/netgraph/netflow/netflow.c ============================================================================== --- head/sys/netgraph/netflow/netflow.c Thu Jan 14 11:25:28 2016 (r293913) +++ head/sys/netgraph/netflow/netflow.c Thu Jan 14 13:14:12 2016 (r293914) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -307,8 +308,9 @@ hash_insert(priv_p priv, struct flow_has int plen, uint8_t flags, uint8_t tcp_flags) { struct flow_entry *fle; - struct sockaddr_in sin; - struct rtentry *rt; + struct sockaddr_in sin, sin_mask; + struct sockaddr_dl rt_gateway; + struct rt_addrinfo info; mtx_assert(&hsh->mtx, MA_OWNED); @@ -339,23 +341,30 @@ hash_insert(priv_p priv, struct flow_has sin.sin_len = sizeof(struct sockaddr_in); sin.sin_family = AF_INET; sin.sin_addr = fle->f.r.r_dst; - rt = rtalloc1_fib((struct sockaddr *)&sin, 0, 0, r->fib); - if (rt != NULL) { - fle->f.fle_o_ifx = rt->rt_ifp->if_index; - if (rt->rt_flags & RTF_GATEWAY && - rt->rt_gateway->sa_family == AF_INET) + rt_gateway.sdl_len = sizeof(rt_gateway); + sin_mask.sin_len = sizeof(struct sockaddr_in); + bzero(&info, sizeof(info)); + + info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway; + info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin_mask; + + if (rib_lookup_info(r->fib, (struct sockaddr *)&sin, NHR_REF, 0, + &info) == 0) { + fle->f.fle_o_ifx = info.rti_ifp->if_index; + + if (info.rti_flags & RTF_GATEWAY && + rt_gateway.sdl_family == AF_INET) fle->f.next_hop = - ((struct sockaddr_in *)(rt->rt_gateway))->sin_addr; + ((struct sockaddr_in *)&rt_gateway)->sin_addr; - if (rt_mask(rt)) - fle->f.dst_mask = - bitcount32(((struct sockaddr_in *)rt_mask(rt))->sin_addr.s_addr); - else if (rt->rt_flags & RTF_HOST) + if (info.rti_addrs & RTA_NETMASK) + fle->f.dst_mask = bitcount32(sin_mask.sin_addr.s_addr); + else if (info.rti_flags & RTF_HOST) /* Give up. We can't determine mask :( */ fle->f.dst_mask = 32; - RTFREE_LOCKED(rt); + rib_free_info(&info); } } @@ -365,16 +374,20 @@ hash_insert(priv_p priv, struct flow_has sin.sin_len = sizeof(struct sockaddr_in); sin.sin_family = AF_INET; sin.sin_addr = fle->f.r.r_src; - rt = rtalloc1_fib((struct sockaddr *)&sin, 0, 0, r->fib); - if (rt != NULL) { - if (rt_mask(rt)) + + sin_mask.sin_len = sizeof(struct sockaddr_in); + bzero(&info, sizeof(info)); + + info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin_mask; + + if (rib_lookup_info(r->fib, (struct sockaddr *)&sin, 0, 0, + &info) == 0) { + if (info.rti_addrs & RTA_NETMASK) fle->f.src_mask = - bitcount32(((struct sockaddr_in *)rt_mask(rt))->sin_addr.s_addr); - else if (rt->rt_flags & RTF_HOST) + bitcount32(sin_mask.sin_addr.s_addr); + else if (info.rti_flags & RTF_HOST) /* Give up. We can't determine mask :( */ fle->f.src_mask = 32; - - RTFREE_LOCKED(rt); } } @@ -390,14 +403,14 @@ hash_insert(priv_p priv, struct flow_has bitcount32((x).__u6_addr.__u6_addr32[1]) + \ bitcount32((x).__u6_addr.__u6_addr32[2]) + \ bitcount32((x).__u6_addr.__u6_addr32[3]) -#define RT_MASK6(x) (ipv6_masklen(((struct sockaddr_in6 *)rt_mask(x))->sin6_addr)) static int hash6_insert(priv_p priv, struct flow_hash_entry *hsh6, struct flow6_rec *r, int plen, uint8_t flags, uint8_t tcp_flags) { struct flow6_entry *fle6; - struct sockaddr_in6 sin6; - struct rtentry *rt; + struct sockaddr_in6 sin6, sin6_mask; + struct sockaddr_dl rt_gateway; + struct rt_addrinfo info; mtx_assert(&hsh6->mtx, MA_OWNED); @@ -430,22 +443,29 @@ hash6_insert(priv_p priv, struct flow_ha sin6.sin6_family = AF_INET6; sin6.sin6_addr = r->dst.r_dst6; - rt = rtalloc1_fib((struct sockaddr *)&sin6, 0, 0, r->fib); - - if (rt != NULL) { - fle6->f.fle_o_ifx = rt->rt_ifp->if_index; + rt_gateway.sdl_len = sizeof(rt_gateway); + sin6_mask.sin6_len = sizeof(struct sockaddr_in6); + bzero(&info, sizeof(info)); + + info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway; + info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin6_mask; + + if (rib_lookup_info(r->fib, (struct sockaddr *)&sin6, NHR_REF, + 0, &info) == 0) { + fle6->f.fle_o_ifx = info.rti_ifp->if_index; - if (rt->rt_flags & RTF_GATEWAY && - rt->rt_gateway->sa_family == AF_INET6) + if (info.rti_flags & RTF_GATEWAY && + rt_gateway.sdl_family == AF_INET6) fle6->f.n.next_hop6 = - ((struct sockaddr_in6 *)(rt->rt_gateway))->sin6_addr; + ((struct sockaddr_in6 *)&rt_gateway)->sin6_addr; - if (rt_mask(rt)) - fle6->f.dst_mask = RT_MASK6(rt); + if (info.rti_addrs & RTA_NETMASK) + fle6->f.dst_mask = + ipv6_masklen(sin6_mask.sin6_addr); else fle6->f.dst_mask = 128; - RTFREE_LOCKED(rt); + rib_free_info(&info); } } @@ -456,15 +476,18 @@ hash6_insert(priv_p priv, struct flow_ha sin6.sin6_family = AF_INET6; sin6.sin6_addr = r->src.r_src6; - rt = rtalloc1_fib((struct sockaddr *)&sin6, 0, 0, r->fib); + sin6_mask.sin6_len = sizeof(struct sockaddr_in6); + bzero(&info, sizeof(info)); - if (rt != NULL) { - if (rt_mask(rt)) - fle6->f.src_mask = RT_MASK6(rt); + info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin6_mask; + + if (rib_lookup_info(r->fib, (struct sockaddr *)&sin6, 0, 0, + &info) == 0) { + if (info.rti_addrs & RTA_NETMASK) + fle6->f.src_mask = + ipv6_masklen(sin6_mask.sin6_addr); else fle6->f.src_mask = 128; - - RTFREE_LOCKED(rt); } } @@ -474,7 +497,6 @@ hash6_insert(priv_p priv, struct flow_ha return (0); } #undef ipv6_masklen -#undef RT_MASK6 #endif