Skip to content

Commit 5bc2b7b

Browse files
sheftyrolandd
authored andcommitted
RDMA/ucma: Allow user space to specify AF_IB when joining multicast
Allow user space applications to join multicast groups using MGIDs directly. MGIDs may be passed using AF_IB addresses. Since the current multicast join command only supports addresses as large as sockaddr_in6, define a new structure for joining addresses specified using sockaddr_ib. Since AF_IB allows the user to specify the qkey when resolving a remote UD QP address, when joining the multicast group use the qkey value, if one has been assigned. Signed-off-by: Sean Hefty <[email protected]> Signed-off-by: Roland Dreier <[email protected]>
1 parent 209cf2a commit 5bc2b7b

File tree

3 files changed

+62
-14
lines changed

3 files changed

+62
-14
lines changed

drivers/infiniband/core/cma.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -3149,6 +3149,8 @@ static void cma_set_mgid(struct rdma_id_private *id_priv,
31493149
0xFF10A01B)) {
31503150
/* IPv6 address is an SA assigned MGID. */
31513151
memcpy(mgid, &sin6->sin6_addr, sizeof *mgid);
3152+
} else if (addr->sa_family == AF_IB) {
3153+
memcpy(mgid, &((struct sockaddr_ib *) addr)->sib_addr, sizeof *mgid);
31523154
} else if ((addr->sa_family == AF_INET6)) {
31533155
ipv6_ib_mc_map(&sin6->sin6_addr, dev_addr->broadcast, mc_map);
31543156
if (id_priv->id.ps == RDMA_PS_UDP)
@@ -3176,9 +3178,12 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
31763178
if (ret)
31773179
return ret;
31783180

3181+
ret = cma_set_qkey(id_priv, 0);
3182+
if (ret)
3183+
return ret;
3184+
31793185
cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid);
3180-
if (id_priv->id.ps == RDMA_PS_UDP)
3181-
rec.qkey = cpu_to_be32(RDMA_UDP_QKEY);
3186+
rec.qkey = cpu_to_be32(id_priv->qkey);
31823187
rdma_addr_get_sgid(dev_addr, &rec.port_gid);
31833188
rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
31843189
rec.join_state = 1;

drivers/infiniband/core/ucma.c

+44-11
Original file line numberDiff line numberDiff line change
@@ -1229,23 +1229,23 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf,
12291229
return ret;
12301230
}
12311231

1232-
static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
1233-
const char __user *inbuf,
1234-
int in_len, int out_len)
1232+
static ssize_t ucma_process_join(struct ucma_file *file,
1233+
struct rdma_ucm_join_mcast *cmd, int out_len)
12351234
{
1236-
struct rdma_ucm_join_ip_mcast cmd;
12371235
struct rdma_ucm_create_id_resp resp;
12381236
struct ucma_context *ctx;
12391237
struct ucma_multicast *mc;
1238+
struct sockaddr *addr;
12401239
int ret;
12411240

12421241
if (out_len < sizeof(resp))
12431242
return -ENOSPC;
12441243

1245-
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
1246-
return -EFAULT;
1244+
addr = (struct sockaddr *) &cmd->addr;
1245+
if (cmd->reserved || !cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr)))
1246+
return -EINVAL;
12471247

1248-
ctx = ucma_get_ctx(file, cmd.id);
1248+
ctx = ucma_get_ctx(file, cmd->id);
12491249
if (IS_ERR(ctx))
12501250
return PTR_ERR(ctx);
12511251

@@ -1256,14 +1256,14 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
12561256
goto err1;
12571257
}
12581258

1259-
mc->uid = cmd.uid;
1260-
memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr);
1259+
mc->uid = cmd->uid;
1260+
memcpy(&mc->addr, addr, cmd->addr_size);
12611261
ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr, mc);
12621262
if (ret)
12631263
goto err2;
12641264

12651265
resp.id = mc->id;
1266-
if (copy_to_user((void __user *)(unsigned long)cmd.response,
1266+
if (copy_to_user((void __user *)(unsigned long) cmd->response,
12671267
&resp, sizeof(resp))) {
12681268
ret = -EFAULT;
12691269
goto err3;
@@ -1288,6 +1288,38 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
12881288
return ret;
12891289
}
12901290

1291+
static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
1292+
const char __user *inbuf,
1293+
int in_len, int out_len)
1294+
{
1295+
struct rdma_ucm_join_ip_mcast cmd;
1296+
struct rdma_ucm_join_mcast join_cmd;
1297+
1298+
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
1299+
return -EFAULT;
1300+
1301+
join_cmd.response = cmd.response;
1302+
join_cmd.uid = cmd.uid;
1303+
join_cmd.id = cmd.id;
1304+
join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr);
1305+
join_cmd.reserved = 0;
1306+
memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size);
1307+
1308+
return ucma_process_join(file, &join_cmd, out_len);
1309+
}
1310+
1311+
static ssize_t ucma_join_multicast(struct ucma_file *file,
1312+
const char __user *inbuf,
1313+
int in_len, int out_len)
1314+
{
1315+
struct rdma_ucm_join_mcast cmd;
1316+
1317+
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
1318+
return -EFAULT;
1319+
1320+
return ucma_process_join(file, &cmd, out_len);
1321+
}
1322+
12911323
static ssize_t ucma_leave_multicast(struct ucma_file *file,
12921324
const char __user *inbuf,
12931325
int in_len, int out_len)
@@ -1451,7 +1483,8 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
14511483
[RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id,
14521484
[RDMA_USER_CM_CMD_QUERY] = ucma_query,
14531485
[RDMA_USER_CM_CMD_BIND] = ucma_bind,
1454-
[RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr
1486+
[RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr,
1487+
[RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast
14551488
};
14561489

14571490
static ssize_t ucma_write(struct file *filp, const char __user *buf,

include/uapi/rdma/rdma_user_cm.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ enum {
6464
RDMA_USER_CM_CMD_MIGRATE_ID,
6565
RDMA_USER_CM_CMD_QUERY,
6666
RDMA_USER_CM_CMD_BIND,
67-
RDMA_USER_CM_CMD_RESOLVE_ADDR
67+
RDMA_USER_CM_CMD_RESOLVE_ADDR,
68+
RDMA_USER_CM_CMD_JOIN_MCAST
6869
};
6970

7071
/*
@@ -242,6 +243,15 @@ struct rdma_ucm_join_ip_mcast {
242243
__u32 id;
243244
};
244245

246+
struct rdma_ucm_join_mcast {
247+
__u64 response; /* rdma_ucma_create_id_resp */
248+
__u64 uid;
249+
__u32 id;
250+
__u16 addr_size;
251+
__u16 reserved;
252+
struct sockaddr_storage addr;
253+
};
254+
245255
struct rdma_ucm_get_event {
246256
__u64 response;
247257
};

0 commit comments

Comments
 (0)