From owner-svn-src-all@freebsd.org Sat Jan 9 16:34:39 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 95F88A67568; Sat, 9 Jan 2016 16:34:39 +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 6D94A1CB7; Sat, 9 Jan 2016 16:34:39 +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 u09GYcce041674; Sat, 9 Jan 2016 16:34:38 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u09GYbwn041665; Sat, 9 Jan 2016 16:34:37 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201601091634.u09GYbwn041665@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Sat, 9 Jan 2016 16:34:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r293544 - in head/sys: net netinet ofed/drivers/infiniband/ulp/ipoib 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: Sat, 09 Jan 2016 16:34:39 -0000 Author: melifaro Date: Sat Jan 9 16:34:37 2016 New Revision: 293544 URL: https://svnweb.freebsd.org/changeset/base/293544 Log: Finish r275196: do not dereference rtentry in if_output() routines. The only piece of information that is required is rt_flags subset. In particular, if_loop() requires RTF_REJECT and RTF_BLACKHOLE flags to check if this particular mbuf needs to be dropped (and what error should be returned). Note that if_loop() will always return EHOSTUNREACH for "reject" routes regardless of RTF_HOST flag existence. This is due to upcoming routing changes where RTF_HOST value won't be available as lookup result. All other functions require RTF_GATEWAY flag to check if they need to return EHOSTUNREACH instead of EHOSTDOWN error. There are 11 places where non-zero 'struct route' is passed to if_output(). For most of the callers (forwarding, bpf, arp) does not care about exact error value. In fact, the only place where this result is propagated is ip_output(). (ip6_output() passes NULL route to nd6_output_ifp()). Given that, add 3 new 'struct route' flags (RT_REJECT, RT_BLACKHOLE and RT_IS_GW) and inline function (rt_update_ro_flags()) to copy necessary rte flags to ro_flags. Call this function in ip_output() after looking up/ verifying rte. Reviewed by: ae Modified: head/sys/net/if_arcsubr.c head/sys/net/if_ethersubr.c head/sys/net/if_fddisubr.c head/sys/net/if_fwsubr.c head/sys/net/if_iso88025subr.c head/sys/net/if_loop.c head/sys/net/route.h head/sys/netinet/ip_output.c head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c Modified: head/sys/net/if_arcsubr.c ============================================================================== --- head/sys/net/if_arcsubr.c Sat Jan 9 16:33:55 2016 (r293543) +++ head/sys/net/if_arcsubr.c Sat Jan 9 16:34:37 2016 (r293544) @@ -113,9 +113,8 @@ arc_output(struct ifnet *ifp, struct mbu error = 0; #if defined(INET) || defined(INET6) - if (ro != NULL && ro->ro_rt != NULL && - (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) - is_gw = 1; + if (ro != NULL) + is_gw = (ro->ro_flags & RT_HAS_GW) != 0; #endif switch (dst->sa_family) { Modified: head/sys/net/if_ethersubr.c ============================================================================== --- head/sys/net/if_ethersubr.c Sat Jan 9 16:33:55 2016 (r293543) +++ head/sys/net/if_ethersubr.c Sat Jan 9 16:34:37 2016 (r293544) @@ -202,7 +202,6 @@ ether_resolve_addr(struct ifnet *ifp, st uint32_t *pflags) { struct ether_header *eh; - struct rtentry *rt; uint32_t lleflags = 0; int error = 0; #if defined(INET) || defined(INET6) @@ -253,8 +252,7 @@ ether_resolve_addr(struct ifnet *ifp, st } if (error == EHOSTDOWN) { - rt = (ro != NULL) ? ro->ro_rt : NULL; - if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) != 0) + if (ro != NULL && (ro->ro_flags & RT_HAS_GW) != 0) error = EHOSTUNREACH; } Modified: head/sys/net/if_fddisubr.c ============================================================================== --- head/sys/net/if_fddisubr.c Sat Jan 9 16:33:55 2016 (r293543) +++ head/sys/net/if_fddisubr.c Sat Jan 9 16:34:37 2016 (r293544) @@ -119,9 +119,8 @@ fddi_output(struct ifnet *ifp, struct mb getmicrotime(&ifp->if_lastchange); #if defined(INET) || defined(INET6) - if (ro != NULL && ro->ro_rt != NULL && - (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) - is_gw = 1; + if (ro != NULL) + is_gw = (ro->ro_flags & RT_HAS_GW) != 0; #endif switch (dst->sa_family) { Modified: head/sys/net/if_fwsubr.c ============================================================================== --- head/sys/net/if_fwsubr.c Sat Jan 9 16:33:55 2016 (r293543) +++ head/sys/net/if_fwsubr.c Sat Jan 9 16:34:37 2016 (r293544) @@ -106,9 +106,8 @@ firewire_output(struct ifnet *ifp, struc } #if defined(INET) || defined(INET6) - if (ro != NULL && ro->ro_rt != NULL && - (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) - is_gw = 1; + if (ro != NULL) + is_gw = (ro->ro_flags & RT_HAS_GW) != 0; #endif /* * For unicast, we make a tag to store the lladdr of the @@ -145,10 +144,6 @@ firewire_output(struct ifnet *ifp, struc * doesn't fit into the arp model. */ if (unicast) { - is_gw = 0; - if (ro != NULL && ro->ro_rt != NULL && - (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) - is_gw = 1; error = arpresolve(ifp, is_gw, m, dst, (u_char *) destfw, NULL); if (error) return (error == EWOULDBLOCK ? 0 : error); Modified: head/sys/net/if_iso88025subr.c ============================================================================== --- head/sys/net/if_iso88025subr.c Sat Jan 9 16:33:55 2016 (r293543) +++ head/sys/net/if_iso88025subr.c Sat Jan 9 16:34:37 2016 (r293544) @@ -214,12 +214,8 @@ iso88025_output(struct ifnet *ifp, struc struct rtentry *rt0 = NULL; int is_gw = 0; - if (ro != NULL) { - rt0 = ro->ro_rt; - if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0) - is_gw = 1; - } - + if (ro != NULL) + is_gw = (ro->ro_flags & RT_HAS_GW) != 0; #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); if (error) Modified: head/sys/net/if_loop.c ============================================================================== --- head/sys/net/if_loop.c Sat Jan 9 16:33:55 2016 (r293543) +++ head/sys/net/if_loop.c Sat Jan 9 16:34:37 2016 (r293544) @@ -202,15 +202,12 @@ looutput(struct ifnet *ifp, struct mbuf struct route *ro) { u_int32_t af; - struct rtentry *rt = NULL; #ifdef MAC int error; #endif M_ASSERTPKTHDR(m); /* check if we have the packet header */ - if (ro != NULL) - rt = ro->ro_rt; #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); if (error) { @@ -219,10 +216,9 @@ looutput(struct ifnet *ifp, struct mbuf } #endif - if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) { + if (ro != NULL && ro->ro_flags & (RT_REJECT|RT_BLACKHOLE)) { m_freem(m); - return (rt->rt_flags & RTF_BLACKHOLE ? 0 : - rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); + return (ro->ro_flags & RT_BLACKHOLE ? 0 : EHOSTUNREACH); } if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); Modified: head/sys/net/route.h ============================================================================== --- head/sys/net/route.h Sat Jan 9 16:33:55 2016 (r293543) +++ head/sys/net/route.h Sat Jan 9 16:34:37 2016 (r293544) @@ -64,9 +64,13 @@ struct route { #define RT_CACHING_CONTEXT 0x1 /* XXX: not used anywhere */ #define RT_NORTREF 0x2 /* doesn't hold reference on ro_rt */ -#define RT_L2_ME (1 << RT_L2_ME_BIT) -#define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT) -#define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT) +#define RT_L2_ME (1 << RT_L2_ME_BIT) /* 0x0004 */ +#define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT) /* 0x0008 */ +#define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT) /* 0x0010 */ + +#define RT_REJECT 0x0020 /* Destination is reject */ +#define RT_BLACKHOLE 0x0040 /* Destination is blackhole */ +#define RT_HAS_GW 0x0080 /* Destination has GW */ struct rt_metrics { u_long rmx_locks; /* Kernel must leave these values alone */ @@ -215,6 +219,19 @@ fib_rte_to_nh_flags(int rt_flags) return (res); } +/* rte<>ro_flags translation */ +static inline void +rt_update_ro_flags(struct route *ro) +{ + int rt_flags = ro->ro_rt->rt_flags; + + ro->ro_flags &= ~ (RT_REJECT|RT_BLACKHOLE|RT_HAS_GW); + + ro->ro_flags = (rt_flags & RTF_REJECT) ? RT_REJECT : 0; + ro->ro_flags |= (rt_flags & RTF_BLACKHOLE) ? RT_BLACKHOLE : 0; + ro->ro_flags |= (rt_flags & RTF_GATEWAY) ? RT_HAS_GW : 0; +} + /* * Routing statistics. */ Modified: head/sys/netinet/ip_output.c ============================================================================== --- head/sys/netinet/ip_output.c Sat Jan 9 16:33:55 2016 (r293543) +++ head/sys/netinet/ip_output.c Sat Jan 9 16:34:37 2016 (r293544) @@ -376,6 +376,7 @@ again: ia = ifatoia(rte->rt_ifa); ifp = rte->rt_ifp; counter_u64_add(rte->rt_pksent, 1); + rt_update_ro_flags(ro); if (rte->rt_flags & RTF_GATEWAY) gw = (struct sockaddr_in *)rte->rt_gateway; if (rte->rt_flags & RTF_HOST) Modified: head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c ============================================================================== --- head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c Sat Jan 9 16:33:55 2016 (r293543) +++ head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c Sat Jan 9 16:34:37 2016 (r293544) @@ -1260,16 +1260,12 @@ ipoib_output(struct ifnet *ifp, struct m #if defined(INET) || defined(INET6) struct llentry *lle = NULL; #endif - struct rtentry *rt0 = NULL; struct ipoib_header *eh; int error = 0, is_gw = 0; short type; - if (ro != NULL) { - rt0 = ro->ro_rt; - if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0) - is_gw = 1; - } + if (ro != NULL) + is_gw = (ro->ro_flags & RT_HAS_GW) != 0; #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); if (error)