From owner-svn-src-projects@freebsd.org Sun Aug 23 18:27:30 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 BD9209C1A6C for ; Sun, 23 Aug 2015 18:27:30 +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 ADACB1813; Sun, 23 Aug 2015 18:27:30 +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 t7NIRUSJ047341; Sun, 23 Aug 2015 18:27:30 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t7NIRTkk047337; Sun, 23 Aug 2015 18:27:29 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201508231827.t7NIRTkk047337@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:27:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r287065 - in projects/routing/sys: net netinet netinet6 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:27:30 -0000 Author: melifaro Date: Sun Aug 23 18:27:28 2015 New Revision: 287065 URL: https://svnweb.freebsd.org/changeset/base/287065 Log: Convert lle rtchecks to use new routing API. For inet/ case, this involves reverting r225947 which seem to be pretty strange commit and should be reverted in HEAD ad well. Modified: projects/routing/sys/net/rt_nhops.c projects/routing/sys/net/rt_nhops.h projects/routing/sys/netinet/in.c projects/routing/sys/netinet6/in6.c Modified: projects/routing/sys/net/rt_nhops.c ============================================================================== --- projects/routing/sys/net/rt_nhops.c Sun Aug 23 18:26:42 2015 (r287064) +++ projects/routing/sys/net/rt_nhops.c Sun Aug 23 18:27:28 2015 (r287065) @@ -498,6 +498,42 @@ fib4_lookup_nh_basic(uint32_t fibnum, st return (ENOENT); } +int +fib4_lookup_nh_ifp(uint32_t fibnum, struct in_addr dst, uint32_t flowid, + struct nhop4_basic *pnh4) +{ + struct radix_node_head *rnh; + struct radix_node *rn; + struct sockaddr_in sin; + struct rtentry *rte; + + KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ifp: 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)) { + fib4_rte_to_nh_basic(rte, dst, pnh4); + RADIX_NODE_HEAD_RUNLOCK(rnh); + pnh4->nh_ifp = rte->rt_ifp; + return (0); + } + } + RADIX_NODE_HEAD_RUNLOCK(rnh); + + return (ENOENT); +} + /* * Performs IPv4 route table lookup on @dst. Returns 0 on success. * Stores extende nexthop info provided @pnh4 structure. Modified: projects/routing/sys/net/rt_nhops.h ============================================================================== --- projects/routing/sys/net/rt_nhops.h Sun Aug 23 18:26:42 2015 (r287064) +++ projects/routing/sys/net/rt_nhops.h Sun Aug 23 18:27:28 2015 (r287065) @@ -169,6 +169,7 @@ struct nhop4_extended { uint64_t spare2[2]; }; +/* Does not differ from nhop6_basic */ struct nhop6_extended { struct ifnet *nh_ifp; /* Logical egress interface */ uint16_t nh_mtu; /* nexthop mtu */ @@ -178,6 +179,27 @@ struct nhop6_extended { uint64_t spare2[2]; }; +/* route info used for control plane purposes */ +struct rt4_basic { + struct in_addr rt_addr; /* route prefix */ + struct in_addr rt_gateway; /* GW used */ + 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 */ + uint16_t spare[2]; +}; + +struct rt6_basic { + struct in6_addr rt_addr; + struct in6_addr rt_gateway; + int rt_flags; + uint16_t rt_mtu; + uint16_t rt_nhop; + uint8_t rt_mask; + uint8_t spare[7]; +}; + struct nhopu_extended { union { struct nhop4_extended nh4; @@ -200,6 +222,8 @@ struct route_compat { int ro_flags; }; +int fib4_lookup_nh_ifp(uint32_t fibnum, struct in_addr dst, uint32_t flowid, + struct nhop4_basic *pnh4); int fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flowid, struct nhop4_basic *pnh4); int fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, Modified: projects/routing/sys/netinet/in.c ============================================================================== --- projects/routing/sys/netinet/in.c Sun Aug 23 18:26:42 2015 (r287064) +++ projects/routing/sys/netinet/in.c Sun Aug 23 18:27:28 2015 (r287065) @@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -71,6 +70,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *); static int in_difaddr_ioctl(caddr_t, struct ifnet *, struct thread *); @@ -1037,16 +1038,14 @@ in_lltable_prefix_free(struct lltable *l static int in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr) { - struct rtentry *rt; + struct nhop4_basic nh4; + struct in_addr dst; KASSERT(l3addr->sa_family == AF_INET, ("sin_family %d", l3addr->sa_family)); - /* XXX rtalloc1_fib should take a const param */ - rt = rtalloc1_fib(__DECONST(struct sockaddr *, l3addr), 0, 0, - ifp->if_fib); - - if (rt == NULL) + dst = ((const struct sockaddr_in *)l3addr)->sin_addr; + if (fib4_lookup_nh_ifp(ifp->if_fib, dst, 0, &nh4) != 0) return (EINVAL); /* @@ -1054,57 +1053,26 @@ in_lltable_rtcheck(struct ifnet *ifp, u_ * address, which is a special route inserted by some implementation * such as MANET, and the interface is of the correct type, then * allow for ARP to proceed. + * XXX: !RTF_HOST condition (temporarily) skipped. */ - if (rt->rt_flags & RTF_GATEWAY) { - if (!(rt->rt_flags & RTF_HOST) || !rt->rt_ifp || - rt->rt_ifp->if_type != IFT_ETHER || - (rt->rt_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 || - memcmp(rt->rt_gateway->sa_data, l3addr->sa_data, - sizeof(in_addr_t)) != 0) { - RTFREE_LOCKED(rt); - return (EINVAL); - } - } - - /* - * Make sure that at least the destination address is covered - * by the route. This is for handling the case where 2 or more - * interfaces have the same prefix. An incoming packet arrives - * on one interface and the corresponding outgoing packet leaves - * another interface. - */ - if (!(rt->rt_flags & RTF_HOST) && rt->rt_ifp != ifp) { - const char *sa, *mask, *addr, *lim; - int len; - - mask = (const char *)rt_mask(rt); - /* - * Just being extra cautious to avoid some custom - * code getting into trouble. - */ - if (mask == NULL) { - RTFREE_LOCKED(rt); + if (nh4.nh_flags & NHF_GATEWAY) { + if (nh4.nh_ifp->if_type != IFT_ETHER || + (nh4.nh_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 || + nh4.nh_addr.s_addr != dst.s_addr) { return (EINVAL); } - sa = (const char *)rt_key(rt); - addr = (const char *)l3addr; - len = ((const struct sockaddr_in *)l3addr)->sin_len; - lim = addr + len; + return (0); + } - for ( ; addr < lim; sa++, mask++, addr++) { - if ((*sa ^ *addr) & *mask) { + if (((nh4.nh_flags & NHF_GATEWAY) != 0) || nh4.nh_ifp != ifp) { #ifdef DIAGNOSTIC - log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n", - inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr)); + log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n", + inet_ntoa(dst)); #endif - RTFREE_LOCKED(rt); - return (EINVAL); - } - } + return (EINVAL); } - RTFREE_LOCKED(rt); return (0); } Modified: projects/routing/sys/netinet6/in6.c ============================================================================== --- projects/routing/sys/netinet6/in6.c Sun Aug 23 18:26:42 2015 (r287064) +++ projects/routing/sys/netinet6/in6.c Sun Aug 23 18:27:28 2015 (r287065) @@ -110,6 +110,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + VNET_DECLARE(int, icmp6_nodeinfo_oldmcprefix); #define V_icmp6_nodeinfo_oldmcprefix VNET(icmp6_nodeinfo_oldmcprefix) @@ -2146,17 +2148,20 @@ in6_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr) { - struct rtentry *rt; + struct nhop6_basic nh6; + struct in6_addr dst; + uint32_t scopeid; + int error; char ip6buf[INET6_ADDRSTRLEN]; KASSERT(l3addr->sa_family == AF_INET6, ("sin_family %d", l3addr->sa_family)); /* Our local addresses are always only installed on the default FIB. */ - /* XXX rtalloc1 should take a const param */ - rt = in6_rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0, - RT_DEFAULT_FIB); - if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) || rt->rt_ifp != ifp) { + + in6_splitscope(&((const struct sockaddr_in6 *)l3addr)->sin6_addr, &dst, &scopeid); + error = fib6_lookup_nh_ifp(RT_DEFAULT_FIB, &dst, scopeid, 0, &nh6); + if (error != 0 || ((nh6.nh_flags & NHF_GATEWAY) != 0) || nh6.nh_ifp != ifp) { struct ifaddr *ifa; /* * Create an ND6 cache for an IPv6 neighbor @@ -2166,17 +2171,12 @@ in6_lltable_rtcheck(struct ifnet *ifp, ifa = ifaof_ifpforaddr(__DECONST(struct sockaddr *, l3addr), ifp); if (ifa != NULL) { ifa_free(ifa); - if (rt != NULL) - RTFREE_LOCKED(rt); return 0; } log(LOG_INFO, "IPv6 address: \"%s\" is not on the network\n", ip6_sprintf(ip6buf, &((const struct sockaddr_in6 *)l3addr)->sin6_addr)); - if (rt != NULL) - RTFREE_LOCKED(rt); return EINVAL; } - RTFREE_LOCKED(rt); return 0; }