Skip to content

Commit b8cab5d

Browse files
haggaiedledford
authored andcommitted
IB/cma: Accept connection without a valid netdev on RoCE
The netdev checks recently added to RDMA CM expect a valid netdev to be found for both InfiniBand and RoCE, but the code that find a netdev is only implemented for InfiniBand. Currently RoCE doesn't provide an API to find the netdev matching a given set of parameters, so this patch just disables the netdev enforcement for each incoming connections when the link layer is RoCE. Fixes: 4c21b5b ("IB/cma: Add net_dev and private data checks to RDMA CM") Reported-by: Kamal Heib <[email protected]> Signed-off-by: Haggai Eran <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent f022fa8 commit b8cab5d

File tree

1 file changed

+40
-14
lines changed
  • drivers/infiniband/core

1 file changed

+40
-14
lines changed

drivers/infiniband/core/cma.c

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,14 +1232,32 @@ static bool cma_match_private_data(struct rdma_id_private *id_priv,
12321232
return true;
12331233
}
12341234

1235+
static bool cma_protocol_roce_dev_port(struct ib_device *device, int port_num)
1236+
{
1237+
enum rdma_link_layer ll = rdma_port_get_link_layer(device, port_num);
1238+
enum rdma_transport_type transport =
1239+
rdma_node_get_transport(device->node_type);
1240+
1241+
return ll == IB_LINK_LAYER_ETHERNET && transport == RDMA_TRANSPORT_IB;
1242+
}
1243+
1244+
static bool cma_protocol_roce(const struct rdma_cm_id *id)
1245+
{
1246+
struct ib_device *device = id->device;
1247+
const int port_num = id->port_num ?: rdma_start_port(device);
1248+
1249+
return cma_protocol_roce_dev_port(device, port_num);
1250+
}
1251+
12351252
static bool cma_match_net_dev(const struct rdma_id_private *id_priv,
12361253
const struct net_device *net_dev)
12371254
{
12381255
const struct rdma_addr *addr = &id_priv->id.route.addr;
12391256

12401257
if (!net_dev)
1241-
/* This request is an AF_IB request */
1242-
return addr->src_addr.ss_family == AF_IB;
1258+
/* This request is an AF_IB request or a RoCE request */
1259+
return addr->src_addr.ss_family == AF_IB ||
1260+
cma_protocol_roce(&id_priv->id);
12431261

12441262
return !addr->dev_addr.bound_dev_if ||
12451263
(net_eq(dev_net(net_dev), &init_net) &&
@@ -1294,6 +1312,10 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id,
12941312
if (PTR_ERR(*net_dev) == -EAFNOSUPPORT) {
12951313
/* Assuming the protocol is AF_IB */
12961314
*net_dev = NULL;
1315+
} else if (cma_protocol_roce_dev_port(req.device, req.port)) {
1316+
/* TODO find the net dev matching the request parameters
1317+
* through the RoCE GID table */
1318+
*net_dev = NULL;
12971319
} else {
12981320
return ERR_CAST(*net_dev);
12991321
}
@@ -1593,11 +1615,16 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
15931615
if (ret)
15941616
goto err;
15951617
} else {
1596-
/* An AF_IB connection */
1597-
WARN_ON_ONCE(ss_family != AF_IB);
1598-
1599-
cma_translate_ib((struct sockaddr_ib *)cma_src_addr(id_priv),
1600-
&rt->addr.dev_addr);
1618+
if (!cma_protocol_roce(listen_id) &&
1619+
cma_any_addr(cma_src_addr(id_priv))) {
1620+
rt->addr.dev_addr.dev_type = ARPHRD_INFINIBAND;
1621+
rdma_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid);
1622+
ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey));
1623+
} else if (!cma_any_addr(cma_src_addr(id_priv))) {
1624+
ret = cma_translate_addr(cma_src_addr(id_priv), &rt->addr.dev_addr);
1625+
if (ret)
1626+
goto err;
1627+
}
16011628
}
16021629
rdma_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid);
16031630

@@ -1635,13 +1662,12 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
16351662
if (ret)
16361663
goto err;
16371664
} else {
1638-
/* An AF_IB connection */
1639-
WARN_ON_ONCE(ss_family != AF_IB);
1640-
1641-
if (!cma_any_addr(cma_src_addr(id_priv)))
1642-
cma_translate_ib((struct sockaddr_ib *)
1643-
cma_src_addr(id_priv),
1644-
&id->route.addr.dev_addr);
1665+
if (!cma_any_addr(cma_src_addr(id_priv))) {
1666+
ret = cma_translate_addr(cma_src_addr(id_priv),
1667+
&id->route.addr.dev_addr);
1668+
if (ret)
1669+
goto err;
1670+
}
16451671
}
16461672

16471673
id_priv->state = RDMA_CM_CONNECT;

0 commit comments

Comments
 (0)