From owner-svn-src-projects@FreeBSD.ORG Sat Nov 29 15:02:47 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 40BE43D3; Sat, 29 Nov 2014 15:02:47 +0000 (UTC) Received: from svn.freebsd.org (svn.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 2DB91107; Sat, 29 Nov 2014 15:02:47 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sATF2lgE036075; Sat, 29 Nov 2014 15:02:47 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sATF2kRA036067; Sat, 29 Nov 2014 15:02:46 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201411291502.sATF2kRA036067@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Sat, 29 Nov 2014 15:02:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r275243 - projects/routing/sys/net 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.18-1 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: Sat, 29 Nov 2014 15:02:47 -0000 Author: melifaro Date: Sat Nov 29 15:02:45 2014 New Revision: 275243 URL: https://svnweb.freebsd.org/changeset/base/275243 Log: * Make ifa_add_loopback_route() prepare gw before insertion. * Temporarily move ifa_switch_loopback_route() implementation to route.c Modified: projects/routing/sys/net/if.c projects/routing/sys/net/route.c projects/routing/sys/net/route.h Modified: projects/routing/sys/net/if.c ============================================================================== --- projects/routing/sys/net/if.c Sat Nov 29 14:30:39 2014 (r275242) +++ projects/routing/sys/net/if.c Sat Nov 29 15:02:45 2014 (r275243) @@ -1528,27 +1528,28 @@ ifa_free(struct ifaddr *ifa) int ifa_add_loopback_route(struct ifaddr *ifa, struct sockaddr *ia) { - int error = 0; - struct rtentry *rt = NULL; + int error; struct rt_addrinfo info; - static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; + struct sockaddr_dl null_sdl; + struct ifnet *ifp; + + ifp = ifa->ifa_ifp; bzero(&info, sizeof(info)); info.rti_ifp = V_loif; info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC; info.rti_info[RTAX_DST] = ia; info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl; - error = rtrequest1_fib(RTM_ADD, &info, &rt, ifa->ifa_ifp->if_fib); - if (error == 0 && rt != NULL) { - RT_LOCK(rt); - ((struct sockaddr_dl *)rt->rt_gateway)->sdl_type = - ifa->ifa_ifp->if_type; - ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index = - ifa->ifa_ifp->if_index; - RT_REMREF(rt); - RT_UNLOCK(rt); - } else if (error != 0) + bzero(&null_sdl, sizeof(null_sdl)); + null_sdl.sdl_len = sizeof(null_sdl); + null_sdl.sdl_family = AF_LINK; + null_sdl.sdl_type = ifp->if_type; + null_sdl.sdl_index = ifp->if_index; + + error = rtrequest1_fib(RTM_ADD, &info, NULL, ifp->if_fib); + + if (error != 0) log(LOG_DEBUG, "%s: insertion failed: %u\n", __func__, error); return (error); @@ -1581,20 +1582,8 @@ ifa_del_loopback_route(struct ifaddr *if int ifa_switch_loopback_route(struct ifaddr *ifa, struct sockaddr *sa, int fib) { - struct rtentry *rt; - - rt = rtalloc1_fib(sa, 0, 0, fib); - if (rt == NULL) { - log(LOG_DEBUG, "%s: fail", __func__); - return (EHOSTUNREACH); - } - ((struct sockaddr_dl *)rt->rt_gateway)->sdl_type = - ifa->ifa_ifp->if_type; - ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index = - ifa->ifa_ifp->if_index; - RTFREE_LOCKED(rt); - return (0); + return (rt_switch_loopback_route(fib, sa, ifa->ifa_ifp)); } /* Modified: projects/routing/sys/net/route.c ============================================================================== --- projects/routing/sys/net/route.c Sat Nov 29 14:30:39 2014 (r275242) +++ projects/routing/sys/net/route.c Sat Nov 29 15:02:45 2014 (r275243) @@ -2027,6 +2027,52 @@ rtinit(struct ifaddr *ifa, int cmd, int } /* + * Switches 'real' interface index inside rt_gateway + * for address in @dst to interface @ifp. + * + * Returns 0 on success/ + */ +int +rt_switch_loopback_route(uint32_t fibnum, struct sockaddr *dst, + struct ifnet *ifp) +{ + struct rib_head *rh; + struct radix_node *rn; + struct rtentry *rt; + struct sockaddr_dl *sdl; + + KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum")); + rh = rt_tables_get_rnh(fibnum, dst->sa_family); + if (rh == NULL) + return (EHOSTUNREACH); + + RIB_CFG_WLOCK(rh); + rn = rh->rnh_matchaddr(dst, &rh->head); + if (rn == NULL && ((rn->rn_flags & RNF_ROOT) != 0)) { + RIB_CFG_WUNLOCK(rh); + return (EHOSTUNREACH); + } + rt = RNTORT(rn); + + /* Ensure we have found host route */ + if (rt_mask(rt) == NULL) { + sdl = (struct sockaddr_dl *)rt->rt_gateway; + RIB_WLOCK(rh); + sdl->sdl_type = ifp->if_type; + sdl->sdl_index = ifp->if_index; + RIB_WUNLOCK(rh); + } else + rt = NULL; + + RIB_CFG_WUNLOCK(rh); + + if (rt == NULL) + return (EHOSTUNREACH); + + return (0); +} + +/* * Announce interface address arrival/withdraw * Returns 0 on success. */ Modified: projects/routing/sys/net/route.h ============================================================================== --- projects/routing/sys/net/route.h Sat Nov 29 14:30:39 2014 (r275242) +++ projects/routing/sys/net/route.h Sat Nov 29 15:02:45 2014 (r275243) @@ -338,6 +338,7 @@ typedef int rt_walktree_f_t(struct rtent typedef void rt_setwarg_t(struct rib_head *, uint32_t, int, void *); void rt_foreach_fib(int af, rt_setwarg_t *, rt_walktree_f_t *, void *); void rt_flushifroutes(struct ifnet *ifp); +int rt_switch_loopback_route(uint32_t, struct sockaddr *, struct ifnet *); /* XXX MRT COMPAT VERSIONS THAT SET UNIVERSE to 0 */ /* Thes are used by old code not yet converted to use multiple FIBS */