svn commit: r275243 - projects/routing/sys/net
Alexander V. Chernikov
melifaro at FreeBSD.org
Sat Nov 29 15:02:47 UTC 2014
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 */
More information about the svn-src-projects
mailing list