Index: head/sys/ofed/drivers/infiniband/core/ib_addr.c =================================================================== --- head/sys/ofed/drivers/infiniband/core/ib_addr.c +++ head/sys/ofed/drivers/infiniband/core/ib_addr.c @@ -44,14 +44,17 @@ #include #include #include +#include #include #include #include +#include #include #include #include #include +#include #include "core_priv.h" @@ -275,11 +278,13 @@ struct sockaddr_in dst_tmp = *dst_in; in_port_t src_port; struct sockaddr *saddr = NULL; - struct rtentry *rte; + struct nhop_object *nh; struct ifnet *ifp; int error; int type; + NET_EPOCH_ASSERT(); + /* set VNET, if any */ CURVNET_SET(addr->net); @@ -293,8 +298,7 @@ type |= ADDR_DST_ANY; /* - * Make sure the socket address length field - * is set, else rtalloc1() will fail. + * Make sure the socket address length field is set. */ dst_tmp.sin_len = sizeof(dst_tmp); @@ -303,16 +307,11 @@ case ADDR_VALID: case ADDR_SRC_ANY: /* regular destination route lookup */ - rte = rtalloc1((struct sockaddr *)&dst_tmp, 1, 0); - if (rte == NULL) { + nh = fib4_lookup(RT_DEFAULT_FIB, dst_tmp.sin_addr,0,NHR_NONE,0); + if (nh == NULL) { error = EHOSTUNREACH; goto done; - } else if (rte->rt_ifp == NULL || RT_LINK_IS_UP(rte->rt_ifp) == 0) { - RTFREE_LOCKED(rte); - error = EHOSTUNREACH; - goto done; } - RT_UNLOCK(rte); break; default: error = ENETUNREACH; @@ -332,14 +331,14 @@ /* check source interface */ if (ifp == NULL) { error = ENETUNREACH; - goto error_rt_free; + goto done; } else if (ifp->if_flags & IFF_LOOPBACK) { /* * Source address cannot be a loopback device. */ error = EHOSTUNREACH; goto error_put_ifp; - } else if (rte->rt_ifp->if_flags & IFF_LOOPBACK) { + } else if (nh->nh_ifp->if_flags & IFF_LOOPBACK) { if (memcmp(&src_in->sin_addr, &dst_in->sin_addr, sizeof(src_in->sin_addr))) { /* @@ -352,9 +351,9 @@ } /* get destination network interface from route */ dev_put(ifp); - ifp = rte->rt_ifp; + ifp = nh->nh_ifp; dev_hold(ifp); - } else if (ifp != rte->rt_ifp) { + } else if (ifp != nh->nh_ifp) { /* * Source and destination interfaces are * different. @@ -365,13 +364,13 @@ break; case ADDR_SRC_ANY: /* check for loopback device */ - if (rte->rt_ifp->if_flags & IFF_LOOPBACK) + if (nh->nh_ifp->if_flags & IFF_LOOPBACK) saddr = (struct sockaddr *)&dst_tmp; else - saddr = rte->rt_ifa->ifa_addr; + saddr = nh->nh_ifa->ifa_addr; /* get destination network interface from route */ - ifp = rte->rt_ifp; + ifp = nh->nh_ifp; dev_hold(ifp); break; default: @@ -386,7 +385,7 @@ ifp->if_addrlen, MAX_ADDR_LEN); error = 0; } else if (IN_MULTICAST(ntohl(dst_tmp.sin_addr.s_addr))) { - bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0; + bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0; error = addr_resolve_multi(edst, ifp, (struct sockaddr *)&dst_tmp); if (error != 0) goto error_put_ifp; @@ -396,10 +395,10 @@ memset(edst, 0, MAX_ADDR_LEN); error = 0; } else { - bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0; + bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0; memset(edst, 0, MAX_ADDR_LEN); error = arpresolve(ifp, is_gw, NULL, is_gw ? - rte->rt_gateway : (const struct sockaddr *)&dst_tmp, + &nh->gw_sa : (const struct sockaddr *)&dst_tmp, edst, NULL, NULL); if (error != 0) goto error_put_ifp; @@ -416,17 +415,12 @@ src_in->sin_port = src_port; /* preserve port number */ } - if (rte != NULL) - RTFREE(rte); - *ifpp = ifp; goto done; error_put_ifp: dev_put(ifp); -error_rt_free: - RTFREE(rte); done: CURVNET_RESTORE(); @@ -460,11 +454,13 @@ struct sockaddr_in6 dst_tmp = *dst_in; in_port_t src_port; struct sockaddr *saddr = NULL; - struct rtentry *rte; + struct nhop_object *nh; struct ifnet *ifp; int error; int type; + NET_EPOCH_ASSERT(); + /* set VNET, if any */ CURVNET_SET(addr->net); @@ -478,14 +474,13 @@ type |= ADDR_DST_ANY; /* - * Make sure the socket address length field - * is set, else rtalloc1() will fail. + * Make sure the socket address length field is set. */ dst_tmp.sin6_len = sizeof(dst_tmp); /* - * Make sure the scope ID gets embedded, else rtalloc1() will - * resolve to the loopback interface. + * Make sure the scope ID gets embedded, else nd6_resolve() will + * not find the record. */ dst_tmp.sin6_scope_id = addr->bound_dev_if; sa6_embedscope(&dst_tmp, 0); @@ -502,16 +497,12 @@ /* FALLTHROUGH */ case ADDR_SRC_ANY: /* regular destination route lookup */ - rte = rtalloc1((struct sockaddr *)&dst_tmp, 1, 0); - if (rte == NULL) { + nh = fib6_lookup(RT_DEFAULT_FIB, &dst_in->sin6_addr, + addr->bound_dev_if, NHR_NONE, 0); + if (nh == NULL) { error = EHOSTUNREACH; goto done; - } else if (rte->rt_ifp == NULL || RT_LINK_IS_UP(rte->rt_ifp) == 0) { - RTFREE_LOCKED(rte); - error = EHOSTUNREACH; - goto done; } - RT_UNLOCK(rte); break; default: error = ENETUNREACH; @@ -531,14 +522,14 @@ /* check source interface */ if (ifp == NULL) { error = ENETUNREACH; - goto error_rt_free; + goto done; } else if (ifp->if_flags & IFF_LOOPBACK) { /* * Source address cannot be a loopback device. */ error = EHOSTUNREACH; goto error_put_ifp; - } else if (rte->rt_ifp->if_flags & IFF_LOOPBACK) { + } else if (nh->nh_ifp->if_flags & IFF_LOOPBACK) { if (memcmp(&src_in->sin6_addr, &dst_in->sin6_addr, sizeof(src_in->sin6_addr))) { /* @@ -551,9 +542,9 @@ } /* get destination network interface from route */ dev_put(ifp); - ifp = rte->rt_ifp; + ifp = nh->nh_ifp; dev_hold(ifp); - } else if (ifp != rte->rt_ifp) { + } else if (ifp != nh->nh_ifp) { /* * Source and destination interfaces are * different. @@ -564,13 +555,13 @@ break; case ADDR_SRC_ANY: /* check for loopback device */ - if (rte->rt_ifp->if_flags & IFF_LOOPBACK) + if (nh->nh_ifp->if_flags & IFF_LOOPBACK) saddr = (struct sockaddr *)&dst_tmp; else - saddr = rte->rt_ifa->ifa_addr; + saddr = nh->nh_ifa->ifa_addr; /* get destination network interface from route */ - ifp = rte->rt_ifp; + ifp = nh->nh_ifp; dev_hold(ifp); break; default: @@ -581,21 +572,21 @@ * Step 3 - resolve destination MAC address */ if (IN6_IS_ADDR_MULTICAST(&dst_tmp.sin6_addr)) { - bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0; + bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0; error = addr_resolve_multi(edst, ifp, (struct sockaddr *)&dst_tmp); if (error != 0) goto error_put_ifp; else if (is_gw) addr->network = RDMA_NETWORK_IPV6; - } else if (rte->rt_ifp->if_flags & IFF_LOOPBACK) { + } else if (nh->nh_ifp->if_flags & IFF_LOOPBACK) { memset(edst, 0, MAX_ADDR_LEN); error = 0; } else { - bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0; + bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0; memset(edst, 0, MAX_ADDR_LEN); error = nd6_resolve(ifp, is_gw, NULL, is_gw ? - rte->rt_gateway : (const struct sockaddr *)&dst_tmp, + &nh->gw_sa : (const struct sockaddr *)&dst_tmp, edst, NULL, NULL); if (error != 0) goto error_put_ifp; @@ -612,17 +603,12 @@ src_in->sin6_port = src_port; /* preserve port number */ } - if (rte != NULL) - RTFREE(rte); - *ifpp = ifp; goto done; error_put_ifp: dev_put(ifp); -error_rt_free: - RTFREE(rte); done: CURVNET_RESTORE(); Index: head/sys/ofed/drivers/infiniband/core/ib_cma.c =================================================================== --- head/sys/ofed/drivers/infiniband/core/ib_cma.c +++ head/sys/ofed/drivers/infiniband/core/ib_cma.c @@ -50,10 +50,14 @@ #include #include #include +#include #include #include +#include + +#include #include #include @@ -1351,11 +1355,10 @@ const struct sockaddr_in *src_addr) { #ifdef INET - struct sockaddr_in src_tmp = *src_addr; __be32 daddr = dst_addr->sin_addr.s_addr, saddr = src_addr->sin_addr.s_addr; struct net_device *dst_dev; - struct rtentry *rte; + struct nhop_object *nh; bool ret; if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) || @@ -1378,20 +1381,12 @@ if (saddr == daddr) return true; - /* - * Make sure the socket address length field - * is set, else rtalloc1() will fail. - */ - src_tmp.sin_len = sizeof(src_tmp); - CURVNET_SET(net_dev->if_vnet); - rte = rtalloc1((struct sockaddr *)&src_tmp, 1, 0); - if (rte != NULL) { - ret = (rte->rt_ifp == net_dev); - RTFREE_LOCKED(rte); - } else { + nh = fib4_lookup(RT_DEFAULT_FIB, src_addr->sin_addr, 0, NHR_NONE, 0); + if (nh != NULL) + ret = (nh->nh_ifp == net_dev); + else ret = false; - } CURVNET_RESTORE(); return ret; #else @@ -1407,7 +1402,7 @@ struct sockaddr_in6 src_tmp = *src_addr; struct sockaddr_in6 dst_tmp = *dst_addr; struct net_device *dst_dev; - struct rtentry *rte; + struct nhop_object *nh; bool ret; dst_dev = ip6_dev_find(net_dev->if_vnet, dst_tmp.sin6_addr, @@ -1422,15 +1417,8 @@ CURVNET_SET(net_dev->if_vnet); /* - * Make sure the socket address length field - * is set, else rtalloc1() will fail. + * Make sure the scope ID gets embedded. */ - src_tmp.sin6_len = sizeof(src_tmp); - - /* - * Make sure the scope ID gets embedded, else rtalloc1() will - * resolve to the loopback interface. - */ src_tmp.sin6_scope_id = net_dev->if_index; sa6_embedscope(&src_tmp, 0); @@ -1446,13 +1434,12 @@ ret = true; } else { /* non-loopback case */ - rte = rtalloc1((struct sockaddr *)&src_tmp, 1, 0); - if (rte != NULL) { - ret = (rte->rt_ifp == net_dev); - RTFREE_LOCKED(rte); - } else { + nh = fib6_lookup(RT_DEFAULT_FIB, &src_addr->sin6_addr, + net_dev->if_index, NHR_NONE, 0); + if (nh != NULL) + ret = (nh->nh_ifp == net_dev); + else ret = false; - } } CURVNET_RESTORE(); return ret; @@ -1512,6 +1499,7 @@ *src_addr = (struct sockaddr *)&src_addr_storage; struct net_device *net_dev; const union ib_gid *gid = req->has_gid ? &req->local_gid : NULL; + struct epoch_tracker et; int err; err = cma_save_ip_info(listen_addr, src_addr, ib_event, @@ -1530,10 +1518,13 @@ if (!net_dev) return ERR_PTR(-ENODEV); + NET_EPOCH_ENTER(et); if (!validate_net_dev(net_dev, listen_addr, src_addr)) { + NET_EPOCH_EXIT(et); dev_put(net_dev); return ERR_PTR(-EHOSTUNREACH); } + NET_EPOCH_EXIT(et); return net_dev; }