From owner-svn-src-projects@freebsd.org Sun Aug 23 18:28:51 2015 Return-Path: Delivered-To: svn-src-projects@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 9490D9C1ABE for ; Sun, 23 Aug 2015 18:28:51 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::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 849E51B0C; Sun, 23 Aug 2015 18:28:51 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t7NISpr7047530; Sun, 23 Aug 2015 18:28:51 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t7NISocn047526; Sun, 23 Aug 2015 18:28:50 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201508231828.t7NISocn047526@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Sun, 23 Aug 2015 18:28:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r287068 - in projects/routing/sys: net netgraph/netflow X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 23 Aug 2015 18:28:51 -0000 Author: melifaro Date: Sun Aug 23 18:28:50 2015 New Revision: 287068 URL: https://svnweb.freebsd.org/changeset/base/287068 Log: Add new rib4/rib6 series of functions returning per-rte info packed on stack. Convert ng_netflow to use new routing API. Modified: projects/routing/sys/net/rt_nhops.c projects/routing/sys/net/rt_nhops.h projects/routing/sys/netgraph/netflow/netflow.c Modified: projects/routing/sys/net/rt_nhops.c ============================================================================== --- projects/routing/sys/net/rt_nhops.c Sun Aug 23 18:28:17 2015 (r287067) +++ projects/routing/sys/net/rt_nhops.c Sun Aug 23 18:28:50 2015 (r287068) @@ -117,6 +117,8 @@ int fwd_destroy_fib(struct fwd_module *f static inline uint16_t fib_rte_to_nh_flags(int rt_flags); #ifdef INET +static void rib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, + struct rt4_extended *prt4); static void fib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, struct nhop4_extended *pnh4); static void fib4_rte_to_nh_basic(struct rtentry *rte, struct in_addr dst, @@ -452,6 +454,39 @@ fib4_rte_to_nh_extended(struct rtentry * pnh4->nh_src = IA_SIN(ia)->sin_addr; } +static void +rib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, + struct rt4_extended *prt4) +{ + struct sockaddr_in *gw; + struct in_ifaddr *ia; + + /* Do explicit nexthop zero unless we're copying it */ + memset(prt4, 0, sizeof(*prt4)); + + gw = ((struct sockaddr_in *)rt_key(rte)); + prt4->rt_addr = gw->sin_addr; + gw = ((struct sockaddr_in *)rt_mask(rte)); + prt4->rt_mask.s_addr = (gw != NULL) ? + gw->sin_addr.s_addr : INADDR_BROADCAST; + + if (rte->rt_flags & RTF_GATEWAY) { + gw = (struct sockaddr_in *)rte->rt_gateway; + prt4->rt_gateway = gw->sin_addr; + } else + prt4->rt_gateway = dst; + + prt4->rt_lifp = rte->rt_ifp; + prt4->rt_aifp = rte->rt_ifa->ifa_ifp; + prt4->rt_flags = rte->rt_flags; + prt4->rt_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); + + prt4->rt_nhop = 0; /* XXX: fill real nexthop */ + + ia = ifatoia(rte->rt_ifa); + prt4->rt_src = IA_SIN(ia)->sin_addr; +} + /* * Performs IPv4 route table lookup on @dst. Returns 0 on success. * Stores nexthop info provided @pnh4 structure. @@ -597,6 +632,50 @@ fib4_source_to_sa_ext(const struct nhopu sin->sin_addr = pnhu->u.nh4.nh_src; } +int +rib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flowid, + uint32_t flags, struct rt4_extended *prt4) +{ + struct radix_node_head *rnh; + struct radix_node *rn; + struct sockaddr_in sin; + struct rtentry *rte; + + KASSERT((fibnum < rt_numfibs), ("rib4_lookup_nh_ext: bad fibnum")); + rnh = rt_tables_get_rnh(fibnum, AF_INET); + if (rnh == NULL) + return (ENOENT); + + /* Prepare lookup key */ + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(struct sockaddr_in); + sin.sin_addr = dst; + + RADIX_NODE_HEAD_RLOCK(rnh); + rn = rnh->rnh_matchaddr((void *)&sin, rnh); + if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { + rte = RNTORT(rn); + /* Ensure route & ifp is UP */ + if (RT_LINK_IS_UP(rte->rt_ifp)) { + rib4_rte_to_nh_extended(rte, dst, prt4); + if ((flags & NHOP_LOOKUP_REF) != 0) { + /* TODO: Do lwref on egress ifp's */ + } + RADIX_NODE_HEAD_RUNLOCK(rnh); + return (0); + } + } + RADIX_NODE_HEAD_RUNLOCK(rnh); + + return (ENOENT); +} + +void +rib4_free_nh_ext(uint32_t fibnum, struct rt4_extended *prt4) +{ + +} + #endif #ifdef INET6 @@ -907,6 +986,36 @@ fib6_lla_to_nh_extended(struct in6_addr } static int +rib6_lla_to_nh_extended(struct in6_addr *dst, uint32_t scopeid, + struct rt6_extended *prt6) +{ + struct ifnet *ifp; + + ifp = ifnet_byindex_locked(scopeid); + if (ifp == NULL) + return (ENOENT); + + /* Do explicit nexthop zero unless we're copying it */ + memset(prt6, 0, sizeof(*prt6)); + + prt6->rt_addr.s6_addr16[0] = htons(0xFE80); + prt6->rt_mask = 64; /* XXX check RFC */ + + prt6->rt_aifp = ifp; + prt6->rt_lifp = ifp; + /* Check id this is for-us address */ + if (in6_ifawithifp_lla(ifp, dst)) { + if ((ifp = V_loif) != NULL) + prt6->rt_lifp = ifp; + } + + prt6->rt_mtu = IN6_LINKMTU(ifp); + /* No flags set */ + + return (0); +} + +static int fib6_lla_to_nh(struct in6_addr *dst, uint32_t scopeid, struct nhop_prepend *nh, struct ifnet **lifp) { @@ -988,6 +1097,37 @@ fib6_rte_to_nh_extended(struct rtentry * ia = ifatoia6(rte->rt_ifa); } +#define ipv6_masklen(x) bitcount32((x).__u6_addr.__u6_addr32[0]) + \ + bitcount32((x).__u6_addr.__u6_addr32[1]) + \ + bitcount32((x).__u6_addr.__u6_addr32[2]) + \ + bitcount32((x).__u6_addr.__u6_addr32[3]) +static void +rib6_rte_to_nh_extended(struct rtentry *rte, struct in6_addr *dst, + struct rt6_extended *prt6) +{ + struct sockaddr_in6 *gw; + + /* Do explicit nexthop zero unless we're copying it */ + memset(prt6, 0, sizeof(*prt6)); + + gw = ((struct sockaddr_in6 *)rt_key(rte)); + prt6->rt_addr = gw->sin6_addr; + gw = ((struct sockaddr_in6 *)rt_mask(rte)); + prt6->rt_mask = (gw != NULL) ? ipv6_masklen(gw->sin6_addr) : 128; + + if (rte->rt_flags & RTF_GATEWAY) { + gw = (struct sockaddr_in6 *)rte->rt_gateway; + prt6->rt_gateway = gw->sin6_addr; + in6_clearscope(&prt6->rt_gateway); + } else + prt6->rt_gateway = *dst; + + prt6->rt_lifp = rte->rt_ifp; + prt6->rt_aifp = ifnet_byindex(fib6_get_ifa(rte)); + prt6->rt_flags = fib_rte_to_nh_flags(rte->rt_flags); + prt6->rt_mtu = min(rte->rt_mtu, IN6_LINKMTU(rte->rt_ifp)); +} + int fib6_lookup_nh_ifp(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, uint32_t flowid, struct nhop6_basic *pnh6) @@ -999,6 +1139,7 @@ fib6_lookup_nh_ifp(uint32_t fibnum, stru if (IN6_IS_SCOPE_LINKLOCAL(dst)) { /* Do not lookup link-local addresses in rtable */ + /* XXX: Check if dst is local */ return (fib6_lla_to_nh_basic(dst, scopeid, pnh6)); } @@ -1133,6 +1274,59 @@ fib6_free_nh_ext(uint32_t fibnum, struct } +int +rib6_lookup_nh_ext(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, + uint32_t flowid, uint32_t flags, struct rt6_extended *prt6) +{ + struct radix_node_head *rnh; + struct radix_node *rn; + struct sockaddr_in6 sin6; + struct rtentry *rte; + + if (IN6_IS_SCOPE_LINKLOCAL(dst)) { + /* Do not lookup link-local addresses in rtable */ + /* XXX: Do lwref on egress ifp */ + return (rib6_lla_to_nh_extended(dst, scopeid, prt6)); + } + + KASSERT((fibnum < rt_numfibs), ("rib6_lookup_nh_ext: bad fibnum")); + rnh = rt_tables_get_rnh(fibnum, AF_INET6); + if (rnh == NULL) + return (ENOENT); + + /* Prepare lookup key */ + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_addr = *dst; + sin6.sin6_scope_id = scopeid; + sa6_embedscope(&sin6, 0); + + RADIX_NODE_HEAD_RLOCK(rnh); + rn = rnh->rnh_matchaddr((void *)&sin6, rnh); + if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { + rte = RNTORT(rn); + /* Ensure route & ifp is UP */ + if (RT_LINK_IS_UP(rte->rt_ifp)) { + rib6_rte_to_nh_extended(rte, dst, prt6); + if ((flags & NHOP_LOOKUP_REF) != 0) { + /* TODO: Do lwref on egress ifp's */ + } + RADIX_NODE_HEAD_RUNLOCK(rnh); + + return (0); + } + } + RADIX_NODE_HEAD_RUNLOCK(rnh); + + return (ENOENT); +} + +void +rib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *prt6) +{ + +} + #endif void Modified: projects/routing/sys/net/rt_nhops.h ============================================================================== --- projects/routing/sys/net/rt_nhops.h Sun Aug 23 18:28:17 2015 (r287067) +++ projects/routing/sys/net/rt_nhops.h Sun Aug 23 18:28:50 2015 (r287068) @@ -180,23 +180,28 @@ struct nhop6_extended { }; /* route info used for control plane purposes */ -struct rt4_basic { +struct rt4_extended { struct in_addr rt_addr; /* route prefix */ struct in_addr rt_gateway; /* GW used */ + struct ifnet *rt_lifp; /* logical interface */ + struct ifnet *rt_aifp; /* address interface */ int rt_flags; /* Copy of rte flags */ uint16_t rt_mtu; uint16_t rt_nhop; /* nexthop id (might bi mpath) */ struct in_addr rt_mask; /* route mask */ + struct in_addr rt_src; uint16_t spare[2]; }; -struct rt6_basic { +struct rt6_extended { struct in6_addr rt_addr; struct in6_addr rt_gateway; + struct ifnet *rt_lifp; /* logical interface */ + struct ifnet *rt_aifp; /* address interface */ int rt_flags; uint16_t rt_mtu; uint16_t rt_nhop; - uint8_t rt_mask; + uint8_t rt_mask; /*Hopefully, no more non-config masks */ uint8_t spare[7]; }; @@ -232,6 +237,9 @@ void fib4_free_nh_ext(uint32_t fibnum, s #define NHOP_LOOKUP_REF 0x01 void fib4_source_to_sa_ext(const struct nhopu_extended *pnhu, struct sockaddr_in *sin); +int rib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flowid, + uint32_t flags, struct rt4_extended *prt4); +void rib4_free_nh_ext(uint32_t fibnum, struct rt4_extended *prt4); int fib6_lookup_nh_ifp(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, @@ -242,6 +250,9 @@ int fib6_lookup_nh_ext(uint32_t fibnum, uint32_t scopeid, uint32_t flowid, uint32_t flags, struct nhop6_extended *pnh6); void fib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *pnh6); +int rib6_lookup_nh_ext(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, + uint32_t flowid, uint32_t flags, struct rt6_extended *prt6); +void rib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *prt6); void fib_free_nh_ext(uint32_t fibnum, struct nhopu_extended *pnhu); Modified: projects/routing/sys/netgraph/netflow/netflow.c ============================================================================== --- projects/routing/sys/netgraph/netflow/netflow.c Sun Aug 23 18:28:17 2015 (r287067) +++ projects/routing/sys/netgraph/netflow/netflow.c Sun Aug 23 18:28:50 2015 (r287068) @@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -53,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -307,8 +307,7 @@ 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 rt4_extended rt4; mtx_assert(&hsh->mtx, MA_OWNED); @@ -335,46 +334,20 @@ hash_insert(priv_p priv, struct flow_has * fill in out_ifx, dst_mask, nexthop, and dst_as in future releases. */ if ((flags & NG_NETFLOW_CONF_NODSTLOOKUP) == 0) { - bzero(&sin, sizeof(sin)); - 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) - fle->f.next_hop = - ((struct sockaddr_in *)(rt->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) - /* Give up. We can't determine mask :( */ - fle->f.dst_mask = 32; - - RTFREE_LOCKED(rt); + if (rib4_lookup_nh_ext(r->fib, fle->f.r.r_dst, 0, 0, &rt4) != 0) { + fle->f.fle_o_ifx = rt4.rt_lifp->if_index; + if (rt4.rt_flags & RTF_GATEWAY) + fle->f.next_hop = rt4.rt_gateway; + fle->f.dst_mask = bitcount32(rt4.rt_mask.s_addr); } } /* Do route lookup on source address, to fill in src_mask. */ if ((flags & NG_NETFLOW_CONF_NOSRCLOOKUP) == 0) { - bzero(&sin, sizeof(sin)); - 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)) - fle->f.src_mask = - bitcount32(((struct sockaddr_in *)rt_mask(rt))->sin_addr.s_addr); - else if (rt->rt_flags & RTF_HOST) - /* Give up. We can't determine mask :( */ - fle->f.src_mask = 32; - - RTFREE_LOCKED(rt); + if (rib4_lookup_nh_ext(r->fib, fle->f.r.r_src, 0, 0, &rt4) != 0) { + if (rt4.rt_flags & RTF_GATEWAY) + fle->f.next_hop = rt4.rt_gateway; + fle->f.src_mask = bitcount32(rt4.rt_mask.s_addr); } } @@ -396,9 +369,7 @@ hash6_insert(priv_p priv, struct flow_ha int plen, uint8_t flags, uint8_t tcp_flags) { struct flow6_entry *fle6; - struct sockaddr_in6 *src, *dst; - struct rtentry *rt; - struct route_in6 rin6; + struct rt6_extended rt6; mtx_assert(&hsh6->mtx, MA_OWNED); @@ -426,51 +397,18 @@ hash6_insert(priv_p priv, struct flow_ha * fill in out_ifx, dst_mask, nexthop, and dst_as in future releases. */ if ((flags & NG_NETFLOW_CONF_NODSTLOOKUP) == 0) { - bzero(&rin6, sizeof(struct route_in6)); - dst = (struct sockaddr_in6 *)&rin6.ro_dst; - dst->sin6_len = sizeof(struct sockaddr_in6); - dst->sin6_family = AF_INET6; - dst->sin6_addr = r->dst.r_dst6; - - rin6.ro_rt = rtalloc1_fib((struct sockaddr *)dst, 0, 0, r->fib); - - if (rin6.ro_rt != NULL) { - rt = rin6.ro_rt; - fle6->f.fle_o_ifx = rt->rt_ifp->if_index; - - if (rt->rt_flags & RTF_GATEWAY && - rt->rt_gateway->sa_family == AF_INET6) - fle6->f.n.next_hop6 = - ((struct sockaddr_in6 *)(rt->rt_gateway))->sin6_addr; - - if (rt_mask(rt)) - fle6->f.dst_mask = RT_MASK6(rt); - else - fle6->f.dst_mask = 128; - - RTFREE_LOCKED(rt); + if (rib6_lookup_nh_ext(r->fib, &r->dst.r_dst6, 0, 0, 0, &rt6) == 0) { + fle6->f.fle_o_ifx = rt6.rt_lifp->if_index; + if ((rt6.rt_flags & RTF_GATEWAY) != 0) + fle6->f.n.next_hop6 = rt6.rt_gateway; + fle6->f.dst_mask = rt6.rt_mask; } } if ((flags & NG_NETFLOW_CONF_NODSTLOOKUP) == 0) { /* Do route lookup on source address, to fill in src_mask. */ - bzero(&rin6, sizeof(struct route_in6)); - src = (struct sockaddr_in6 *)&rin6.ro_dst; - src->sin6_len = sizeof(struct sockaddr_in6); - src->sin6_family = AF_INET6; - src->sin6_addr = r->src.r_src6; - - rin6.ro_rt = rtalloc1_fib((struct sockaddr *)src, 0, 0, r->fib); - - if (rin6.ro_rt != NULL) { - rt = rin6.ro_rt; - - if (rt_mask(rt)) - fle6->f.src_mask = RT_MASK6(rt); - else - fle6->f.src_mask = 128; - - RTFREE_LOCKED(rt); + if (rib6_lookup_nh_ext(r->fib, &r->src.r_src6, 0, 0, 0, &rt6) == 0) { + fle6->f.dst_mask = rt6.rt_mask; } }